您的位置:首页 > Web前端 > Webpack

webpack生产环境优化及配置总结

2018-04-03 15:22 1016 查看

一 介绍

之前在开发一个react网站项目, 到正式部署到云服务器时才发现对react及webpack生产环境配置没有什么了解, 下面就总结一下自己配置生产环境的内容.

二 需要配置的内容

1. js文件压缩

首先就是要进行打包后的js文件的压缩, 其中要使用
uglifyjs-webpack-plugin
, 首先使用npm安装这个包, 然后在配置文件中加入插件配置项:

// js压缩插件
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');


然后再在plugins插件部分添加它的使用:

...
plugins: [
// 压缩Js
new UglifyJSPlugin({
sourceMap: true
})
]
...


2. css压缩

css压缩配置相对容易, 只要在css-loader的options中加入压缩的选项为true即可, 即:

...
{
loader: 'css-loader',
options: {
minimize: true
}
}
...


3. 图片压缩

此处需要配置两个内容: 一是
url-loader
二是
image-webpack-loader
. 两个loader联用可以将各类在引入时进行压缩. 配置如下:

...
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
},
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true,
mozjpeg: {
progressive: true,
quality: 40
},
},
},
]
}
...


image-webpack-loader
中的
mozjpeg
为例,
mozjpeg
是用来压缩jpeg格式文件的配置, 其中的qulity即是其压缩质量为40%, 其余对不同的图片格式使用了不同的技术去压缩, 需要分别配置.

在配置时有几个注意的点:

1. 经测试, 在js文件及css文件中引用图片要使用相对路径格式, webpack会将引入的文件单独压缩打包到输出文件夹中. 如
import product1 from '../img/product/product-img1.png'


2. 在webpack官网配置教程中使用的是
file-loader
image-webpack-loader
, 这种配置方式对css中引用的图片无法进行压缩, 所以要使用
url-loader
才可以对css中如
background: url(...)
中引用的图片进行压缩.

4. 提取代码公共部分

可以将代码中公共的部分提取处理单独引用, 其中要使用webpack的CommonsChunkPlugin插件, 配置方法是在plugin中加入相应的内容:

...
plugins: [
// Plugin for code splitting, 抽离出公共部分单独打包
new webpack.optimize.CommonsChunkPlugin({
name: 'common' // Specify the common bundle's name.
})
...
]
...


在抽离出公共部分后, html中也要相应的加入内容, 如:

<script src="common.bundle.js"></script>


5. css单独提取

可以将所有css单独提取为一个文件, 和js等并行进行读取. 其中要使用
ExtractTextPlugin
, 配置方法分两部分, 一是在loader部分配置, 二是在plugin部分配置.

...
{
test: /\.(css|less)$/,
// 此处使用ExtractTextPlugin插件
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
minimize:
dc63
true
}
},
{
loader: 'less-loader'
}
]
})
}
...

plugins: [
// Plugin for code splitting, css单独打包
new ExtractTextPlugin('style.css'),
]
...


此处配置执行打包所有css为
style.css
这个文件, 然后需要在html中也单独引用这一css.

<link rel="stylesheet" href="/public/dist/style.css">


6. react生产环境

react配置生产模式与
process.env.NODE_ENV
环境变量关联, 配置方法是使用 webpack 内置的
DefinePlugin
.

...
plugins: [
// react配置webpack生产模式
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
...


7. react与babel

使用react生产环境时, 在babel中也要相应进行配置, 对开发和生产环境分别进行配置:

"presets": [
"react",
"es2015"
],
"env": {
"development": {
"plugins": [
[
"react-transform",
{
"transforms": [
{
"transform": "react-transform-hmr",
"imports": [
"react"
],
"locals": [
"module"
]
}
]
}
],
[
"syntax-dynamic-import",
[
"import-inspector",
{
"serverSideRequirePath": true
}
]
]
]
},
"production": {
"plugins": [
[
"syntax-dynamic-import",
[
"import-inspector",
{
"serverSideRequirePath": true
}
]
]
]
}
}
}


其中的development和production分别配置了开发环境和生产环境中使用的插件. 如此处的区别就在于生产环境中去除了热更新的部分, 都保留了动态import句法的部分.

另外, 在生产环境进行打包时, 需要在命令行中加入
BABEL_ENV=production
, 告诉babel本次打包是用在生产环境中.

三 webpack配置文件分离

之前在开发时都是直接使用一个
webpack.config.js
配置文件, 如果要区分生产和开发两种环境, 就要对配置文件进行分离. 参考官方教程, 新建
webpack.dev.js
webpack.prod.js
.

然后, 为了避免重复, 要将两种环境下相同的内容放在一个公共的配置文件中, 所以新建
webpack.common.js
用来保存这个部分:

const webpack = require('webpack');
// css代码分割Plugin
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const OUTPUT_PATH = path.resolve(__dirname, 'dist');

module.exports = {
entry: {
index: './app/index.js',
},
output: {
// __dirname: 全局变量, 存储的是文件所在的文件目录
// path.resolve()(node)将一系列路径或路径片段解析为一个绝对路径
path: OUTPUT_PATH,
filename: '[name].bundle.js'
},
module: {
rules: [
{
// test: 一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)
test: /(\.js|\.jsx)$/,
// include/exclude: 手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选)
exclude: /^node_modules$/,
use: {
loader: 'babel-loader'
// 此处的options: {...} 单独提取到了.babelrc中
}
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
},
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true,
mozjpeg: {
progressive: true,
quality: 40
},
},
},
]
},
{
test: /\.(css|less)$/,
// 此处使用ExtractTextPlugin插件
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
minimize: true
}
},
{
loader: 'less-loader'
}
]
})
}
]
},
plugins: [
// Plugin for code splitting, 抽离出公共部分单独打包
new webpack.optimize.CommonsChunkPlugin({
name: 'common' // Specify the common bundle's name.
}),
// Plugin for code splitting, css单独打包
new ExtractTextPlugin('style.css'),
]
};


其中使用公共部分需要用到
webpack-merge
, 需要npm安装一下这个包.

之后在
webpack.dev.js
webpack.prod.js
中分离开发环境和生产环境所用到的代码, 如:

// webpack.dev.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common');

module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
// 本地服务器所加载页面所在目录
contentBase: '../',
// 是否跳转, 单页面时使用ture
historyApiFallback: true,
// inline模式, 表示脚本将会在动态重载时被插入到bundle中
inline: true,
// 允许Hot Module Replacement功能
hot: true
},
plugins: [
// 也用于热加载, 配置后会显示更新的模块名称
new webpack.NamedModulesPlugin(),
// 热加载插件: npm install --save-dev babel-plugin-react-transform react-transform-hmr
new webpack.HotModuleReplacementPlugin(),
]
});


此处在webpack.dev.js中单独抽离出了开发环境的代码, 需要注意的有以下几点:

其中使用了
const common = require('./webpack.common');
来将公共部分引入

公共引入部分使用了
merge()
去和单独的部分进行整合

同理, prod即生产环境也使用同样的方式进行整合, 如:

// webpack.prod.js
const webpack = require('webpack');
// 用于配置文件的合并
const merge = require('webpack-merge');
// js压缩插件 const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
// 抽离出公共部分
const common = require('./webpack.common');

module.exports = merge(common, {
plugins: [
// 压缩Js
new UglifyJSPlugin({
sourceMap: true
}),
// react配置webpack生产模式
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
});


四 NPM Scripts

最后一步要做的就是在package.json中加入开发环境和生产环境中不同的命令, 因为两种环境使用的配置文件不同, 所以要在命令中指定:

"scripts": {
"start": "webpack-dev-server --open --port 3000 --config webpack.dev.js",
"build": "BABEL_ENV=production webpack --config webpack.prod.js"
},


build即生产环境打包, 用
--config
指定了生产环境的配置文件

start即在开发环境中使用, 在3000端口中打开webpack自带的开发服务器, 并且指定了开发环境的配置文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: