webpack开发环境和生产环境的深入理解

以前自己写一小项目时,webpack的配置基本就是一套配置,没有考虑生产环境和开发环境的区分,最近在做一个复杂的商城项目接触到了webpack的高级配置,经过两天的研究,写出了一份目前来说比叫满意的配置,在这里分享一下。

如何区分开发环境和生产环境?

众所周知,webpack时基于node.js平台运行的,要区分开发环境和生产环境还要存,node入手。我们启动webpack时,都需要输入一些命令,npm run 、yarn start之类的,所以我们就从命令行入手,告诉webpack,当前是什么环境。

package.json

{

"name": "webpac-demo",

"version": "1.0.0",

"description": "webpack练习",

"main": "index.js",

"scripts": {

//配置开发环境参数。注意:真实开发中 package.json 文件中不能有注释

"dev": "webpack --env=development",

//配置生产环境参数

"dist": "webpack --env=production",

"start": "webpack-dev-server --env=development"

},

"dependencies": {

"font-awesome": "^4.7.0",

"react": "^16.2.0",

"react-dom": "^16.2.0"

},

"devDependencies":{

...

}

}

这样配置,当我们在命令行输入 npm run dev 和 npm run dist 时,就会附带一些参数到命令行中,有了参数,我们该如何拿到呢?那就要用到 node 的一个命令行参数解析引擎了。

minimist

minimist轻量级的命令行参数解析引擎

// test.js

var args = require('minimist')(process.argv.slice(2));

console.log(args.hello);

$ node test.js --env=production

// production

$ node test.js --env=development

// development

$ node test.js --env

// true 注意:不是空字符串而是true

minimist会把参数解析成一个JSON对象:{key:value},有了这个JSON对象,我们就可以知道,当前的命令是要执行开发打包,还是生产打包了。

// webpack.config.js

const webpack = require('webpack');

//当前项目的绝对路劲

const path = require('path');

// 命令行参数解析引擎

const argv = require('minimist')(process.argv.slice(2));

let env = null;

switch (argv.env) {

case 'production':

//生产环境配置文件名

env = 'webpack.config.prod';

break;

default:

//开发环境配置文件名

env = 'webpack.config.dev';

}

console.log(`当前是 ${argv.env} 打包`);

// 这时候,我们就可以加载相应的wabpack配置了。

module.exports = require( path.resolve( '加载的配置文件路劲',env ) );

webpack开发环境配置和生产环境配置

开发环境配置

在开发环境下,我们首先考虑的是方便开发,方便代码调试,不需要考虑代码合并和css样式分离这些。

这里主要说三个 :1.css模块化;2.模块热替换功能;3.source-map(代码映射)

// 开发环境打包配置

const path = require('path');

const webpack = require('webpack');

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

const dfPath = require('./path')

// webpack配置合并工具

const merge =require('webpack-merge')

const RS = (...arg)=>path.resolve( __dirname , ...arg )

// 合并方式配置

let strategyMerge = merge.strategy({

entry: 'prepend'

});

let config = {

entry: {

app: path.resolve(dfPath.root,'src/app.js')

},

output: {

path: dfPath.dist,

filename: '[name].bundle.js',

publicPath: '/',

chunkFilename: '[name].sepChunk.js'

},

module:{

rules: [

{

test: /\.js$/,

use:['babel-loader'],

exclude: [

dfPath.node_modules

]

},

{

test:/\.css$/,

use:[

'style-loader',

{

loader:'css-loader',

options:{

// css模块化,方便多人开发

module:true,

// 定义模块化css后的类名(默认为hash值,可读性差)path:路劲; name:文件名; local:本地定义的className

localIdentName: '[path][name]__[local]--[hash:base64:5]'

},

}

],

// 排除的文件,遇到这些文件不会用当前 loader 处理,也就不会模块化

exclude:[

RS('./src/common'),

RS('node_modules')

]

},

{

test:/\.css$/,

use:['style-loader','css-loader'],

include:[

RS('./src/common'),

RS('node_modules')

]

},

{

test: /\.(png|jpg|jpeg|gif)$/,

use: ['url-loader?limit=8192'],

}

]

},

plugins:[

// 模块热替换功能

new webpack.HotModuleReplacementPlugin()

],

// 代码映射,方便报错时,找到对应的源代码

devtool: 'cheap-module-eval-source-map',

devServer:{

// 服务器打包后,输出的资源路劲

publicPath:'/',

open:true

}

};

// 导出合并后的webpack配置

module.exports = strategyMerge( base , config );

生产环境配置

相比开发环境,生产环境打包是要最后发布到服务器部署的代码,我们需要尽量保持代码简洁,加载性能最优,不需要调试辅助工具。

我们从这几个方面优化 :1.公共模块拆分,单独打包;2. css文件分离,单独打包输出;3.代码压缩;

// 生产环境配置

const webpack = require('webpack');

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

const path = require('path');

const dfPath = require('./path');

const merge = require('webpack-merge');

// 压缩工具

const ClosureCompilerPlugin = require('webpack-closure-compiler');

// css单独打包插件

const extractTextWebpackPlugin = require('extract-text-webpack-plugin');

const extractCSS = new extractTextWebpackPlugin('assets/css/[name]_[contenthash:6].css');

// weback合并配置

let strategyMerge = merge.strategy({

entry: 'replace',

output: 'replace',

module:{

rules: 'replace'

}

});

let config ={

entry: {

// 公共模块拆分,这些代码会单独打包,一般我们会把引用的框架文件拆分出来,方便浏览器缓存,节省资源。

vender:['react'],

app: path.resolve(dfPath.root,'src/app.js')

},

output: {

path: dfPath.dist,

filename: 'assets/js/[name]_[chunkhash].bundle.js',

publicPath: '/',

chunkFilename: 'assets/js/[name].sepChunk.js',

hashDigestLength: 6

},

module:{

rules: [

{

test: /\.js$/,

use:['babel-loader'],

exclude: [

dfPath.node_modules

]

},

/* 开启 css单独打包 和 css模块化的配置 */

{

test: /\.css$/,

use: extractCSS.extract({

use: [

{

loader: 'css-loader',

options:{

modules: true

}

}

]

})

},

{

test: /\.(png|jpg|jpeg|gif)$/,

use: [

{

loader: 'url-loader',

options:{

limit:8192,

name: '[name]_[hash].[ext]',

outputPath: 'assets/img/'

}

}

],

},

{

test: /\.(mp4|ogg|svg|ico)$/,

use: [

{

loader: 'file-loader',

options:{

name: '[name]_[hash].[ext]',

outputPath: 'assets/media/'

}

}

]

},

{

test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,

use: [

{

loader: 'url-loader',

options:{

limit:10000,

name: '[name]_[hash].[ext]',

outputPath: 'assets/font/',

mimetype: 'application/font-woff'

}

}

]

},

{

test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,

use: [

{

loader: 'url-loader',

options:{

limit:10000,

name: '[name]_[hash].[ext]',

outputPath: 'assets/font/',

mimetype: 'application/octet-stream'

}

}

]

},

{

test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,

use: [

{

loader: 'file-loader',

options:{

name: '[name]_[hash].[ext]',

outputPath: 'assets/font/',

}

}

]

},

{

test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,

use: [

{

loader: 'url-loader',

options:{

limit:10000,

name: '[name]_[hash].[ext]',

outputPath: 'assets/font/',

mimetype: 'image/svg+xml'

}

}

]

},

]

},

plugins:[

extractCSS,

// 设置 process.env(生产环境) 环境变量的快捷方式。

new webpack.EnvironmentPlugin({

NODE_ENV: 'production'

})

,new ClosureCompilerPlugin()

],

devtool: 'source-map'

};

module.exports = strategyMerge(base,config);

以上是 webpack开发环境和生产环境的深入理解 的全部内容, 来源链接: utcz.com/z/349621.html

回到顶部