webpack 项目配置细节

故事:其实我们在做vue开发或者react开发 或者普通的webpack项目的时候 一般可能都是直接copy之前的webpack配置文件或者脚手架,但是当让我们自己配置的时候 或者解读脚手架原理的时候,特别是细节的问题 或多或少都有些迷茫,因此我记录了webpack配置项目的细节

首先需要了解node路径分类

node中路径大致分为5类 __dirname  __filename  process.cwd()  ./ 和 ../

const path = require("path")
console.log(__dirname)
console.log(__filename)
console.log(process.cwd())
console.log(path.resolve('./'))
console.log(path.resolve('../'))复制代码

执行 noed  src/main.js  结果如下


总结:

__dirname : 总是返回被执行的 js 所在文件夹的绝对路径

 __filename:总是返回被执行的 js文件 的绝对路径 

process.cwd(): 总是返回运行 node 命令时所在的文件夹的绝对路径 

./:在 require() 中使用是跟 __dirname 的效果相同,不会因为启动脚本的目录不一样而改变, 在其他情况下跟 process.cwd() 效果相同,是相对于启动脚本所在目录的路径  

../: 和./差不多 只是他是返回的上一级目录 

注意: 在上面我们使用了path.resolve()方法将'./'  和 '../'解析成了绝对路径

·

不得不说一下 node 中的path:

在node.js中,提供了一个path某块,在这个模块中,提供了许多使用的,可被用来处理与转换路径的方法与属性。下面我们就来对这些方法与属性做一下介绍。

在webpack中比较常用的方法就是path.join()path.resolve()

const path = require("path")
console.log(path.join('src','main.js'))
console.log(path.resolve('src','main.js'))复制代码

执行 node  src/main.js  结果如下


总结:

path.join():方法使用平台特定的分隔符把全部给定的 path 片段连接到一起,并规范化生成的路径。

path.resolve:方法会把一个路径或路径片段的序列解析为一个绝对路径。


开始webpack

通过环境变量划分开发环境和生产环境

"scripts": {
    "dev": "set NODE_ENV=development && node src/main.js"
  }复制代码

----------main.js
console.log(process.env.NODE_ENV)

复制代码

注意 node中常用的到的环境变量是NODE_ENV,首先查看是否存在 set NODE_ENV 如果不存在则添加环境变量 set NODE_ENV=development

执行 npm run dev 结果如下


因此 我们常常在项目中如下设置

"scripts": {
    "dev": "set NODE_ENV=development && node build/dev-server.js",
    "build": "set NODE_ENV=production && node build/build.js"
  }

复制代码

开发环境热加载和热更新

一般方法我们都是用webpack-dev-server 做热更新执行webpack-dev-server –config wepack.config.js   配置如下

devServer: {
    historyApiFallback: true, // 404的页面会自动跳转到/页面
    inline: true, // 文件改变自动刷新页面
    port: 8088// 服务器端口 
}

复制代码

但是我们在实际项目中并不会这样做  我们一般会使用中间件 webpack-dev-middleware  webpack-hot-middleware  express 结合使用  因为 webpack-dev-server 实际上是一个轻量级的node.js express服务器,实际上相当于是一个封装好的express的http服务器+调用webpack-dev-middleware。 因此我们使用express服务器进行更多的扩展,结合使用其他的中间件来响应http请求及其他的功能这样扩展性更好更灵活 我们一般通过执行 node build/dev-server.js(配置文件路径)。 中间件,是一个函数,用于访问请求对象、响应对象和web应用中处于请求-响应循环流程中的中间件。它的功能包括:执行任何代码、修改请求和响应对象、终结请求-响应循环和调用堆栈中的下一个中间件。

dev-server.js部分配置如下

//使用Node自带的文件路径工具
const path = require('path');  

//使用express
const express = require('express'); 

//使用express启动一个服务
const app = express(); 

const webpack = require('webpack');

const config = require('../config');

const port = 8088

const webpackdevConfig = require('./webpack.dev.config.js')

//启动webpack进行编译
const compiler = webpack(webpackdevConfig) 


// 启动 webpack-dev-middleware,将 编译后的文件暂存到内存中
const devMiddleware = require('webpack-dev-middleware')(compiler, {
    publicPath: webpackdevConfig.output.publicPath
})

const hotMiddleware = require('webpack-hot-middleware')(compiler, {
    log: () => {}
})

// 服务器部署 webpack 打包的静态资源
app.use(devMiddleware)

// 使用热更新, 如果编译出现错误会实时展示编译错误
app.use(hotMiddleware)

const staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)

//为静态资源提供响应服务
app.use(express.static('./')) 

const server = app.listen(port)   

复制代码

一下可以忽略

webpack.base.config.js简单配置

const path = require('path');
const config = require('../config')
const CleanWebpackPlugin = require('clean-webpack-plugin');
const setPath = function(_path) {
    return path.posix.join(config.dev.assetsSubDirectory, _path)
}


function resolve (dir) {
	return path.join(__dirname, '..', dir)
}


module.exports = {
    resolve: {
	    alias: {
	    	'@': resolve('src')
	    }
	},
    module: {
		rules: [
			{
                test: /\.(png|jpg|gif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 10000,
                        name: setPath('images/[name].[hash:7].[ext]')
                    }
                }]
            },
            { 
                test: /\.scss$/,
                loader: 'style-loader!css-loader!sass-loader'
            }
		]
  	},
    plugins: [
        new CleanWebpackPlugin(['dist'], { 
            root: path.resolve(__dirname, ".."),
            verbose: false 
        })
    ]
}复制代码

webpack.dev.config.js简单配置

const path = require('path');

const webpack = require('webpack')

const config = require('../config')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const webpackbaseConfig = require('./webpack.base.config.js');

const merge = require('webpack-merge')

function resolve (dir) {
	return path.join(__dirname, '..', dir)
}

const assetsSubDirectory = "static"
const oEntry = {
        'bundle':'./src/main.js',
        'vendor': './src/scripts/carousel.js'
    }
Object.keys(oEntry).forEach(function(name) {
	oEntry[name] = ['./build/dev-client'].concat(oEntry[name])
})
module.exports = merge(webpackbaseConfig,{
    entry: oEntry,
    output: {
        path: config.build.assetsRoot,
        publicPath: config.build.assetsPublicPath,
        filename: '[name].js'
    },
    devtool: '#cheap-module-eval-source-map',
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: true
        })
    ]
}) 复制代码

webpack.prod.config.js简单配置

const path = require('path');

const webpack = require('webpack')

const config = require('../config')

const webpackbaseConfig = require('./webpack.base.config.js');

const ExtractTextPlugin = require('extract-text-webpack-plugin')

const CopyWebpackPlugin = require('copy-webpack-plugin')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const merge = require('webpack-merge')

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const setPath = function(_path) {
    return path.posix.join(config.build.assetsSubDirectory, _path)
}
var oEntry = {
        'bundle':'./src/main.js',
        'vendor': './src/scripts/carousel.js'
   	}
module.exports = merge(webpackbaseConfig,{
    entry: oEntry,
    output: {
      	path: config.build.assetsRoot,
      	publicPath: config.build.assetsPublicPath,
    	filename: setPath('js/[name].[chunkhash].js')
    },
    module: {
    	rules: [
    		{
	            test: /\.scss$/,
	            use: ExtractTextPlugin.extract({
	                fallback: "style-loader",
	                use: [
	                	{
	                		loader:'css-loader'
	                	},
	                	{
	                		loader:'sass-loader'
	                	}
	                ]
	            })
	        },
	        {
	      test: /\.html$/,
	      loader: 'html-withimg-loader'
	    }
    	]
    },
	plugins: [
		new webpack.DefinePlugin({
			"process.env" : {
				NODE_ENV : "production"
			}
		}),
		new HtmlWebpackPlugin({
			filename: config.build.index,
			template: 'index.html',
			inject: true,
			minify: {
		        collapseWhitespace: true,
		        collapseInlineTagWhitespace: true,
		        removeComments: true,
		        removeRedundantAttributes: true
		   	}
		}),
		new webpack.optimize.UglifyJsPlugin({
			compress: {
				warnings: false
			},
			sourceMap: true
	    }),
        new ExtractTextPlugin({
            filename: setPath('css/[name].[contenthash].css')
        })/*,
	    new CopyWebpackPlugin([
			{
				from: path.resolve(__dirname, '../static'),
				to: config.build.assetsSubDirectory,
				ignore: ['.*']
			}
	    ])*/
	]
})复制代码


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值