development(开发环境) 和 production(生产环境) 这两个环境下的构建目标存在着巨大差异。
开发环境:我们需要:强大的 source map(源码映射-> debug) 和一个有着 live reloading(实时重新加载) 或 hot module replacement(热模块替换) 能力的 localhost server(本地服务器)。
生产环境:关注点在于压缩 bundle、更轻量的 source map、资源优化等,让包更小,浏览器加载更快。
由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。
打包后的项目目录:
新建build文件夹
提取公共的配置:
webpack.base.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: ['babel-polyfill', './src/index.js'] // 把babel-polyfill,也打包进去用于解析ES6+的一些新语法(Promise等)
},
plugins: [
new HtmlWebpackPlugin({
title: '根据环境分离配置',
template: './public/index.html', // 用于挂载打包后的文件的 模板(ejs,html等),默认为lodash-template
filename: 'index.html', // 打包后的生成的html的路径和文件名,路径的相对于 output.path的
hash: true, //true|false,是否为所有注入的静态资源添加webpack每次编译产生的唯一hash值,添加hash形式如下所示
inject: true,
// 向templat中注入所有静态资源,不同的配置值注入的位置不经相同。
/* 1、true或者body:所有JavaScript资源插入到body元素的底部
2、head: 所有JavaScript资源插入到head元素中
3、false: 所有静态资源css和JavaScript都不会注入到模板文件中 */
favicon: './public/favicon.ico',// 配置ico图标
minify: {// html压缩 配置:html-minifier
removeComments: true, //去掉注释
collapseWhitespace: true, //去掉空行
},
chunks: 'all', // 当有多个入口 ,输出多个html时,指定当前的fliename对应的html文件加载的js包名称(对应 entry配置的文件名 eg: ['app'])
excludeChunks: [], // 和上面相反
showErrors: true, // 如果 webpack 编译出现错误,webpack会将错误信息包裹在一个 pre 标签内,属性的默认值为 true ,也就是显示错误信息。
config: { // 自定义变量 随意配置 htmlWebpackPlugin.options 访问
customerVar: 'ssss'
},
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../dist'), // 绝对路径
// publicPath: '/' // 为了在本地直接打开打包的文件暂时注释
},
module: { // 解析除js json等外的文件类型的解析器
rules: [
{ // 使用babel-loader把一些有兼容性的写法编译成基本的(let const 箭头函数等)
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
}
};
针对环境利用webpack-merge的 merge方法,把相关配置合并进去
webpack.dev.config.js (开发)
const merge = require('webpack-merge');
const common = require('./webpack.base.config.js');
const webpack = require('webpack');
const env = require('../config/dev.conf.js')
module.exports = merge(common, {
devtool: 'inline-source-map', // sourceMap
devServer: {
noInfo: true,// 不在cmd/编译器的控制台打印打包的信息,有警告、错误还是会爆出来
compress: true, // 启用gzip 压缩:
host: "0.0.0.0",// 默认localhost
port: 9000, // 端口
publicPath: "/",
hot: true,// 启用热替换
inline: true,
proxy: { // 代理 基于http-proxy-middleware
"/api": {
target: "http://192.168.152.55:6666",
pathRewrite: { "^/api": "" }
}
},
// https: true,// 启用https服务器 默认http (会被浏览器拦截,可以在浏览器开启)
open: true,//自动打开浏览器
// openPage: 'http://localhost:9000', // 浏览器默认打开的页面
useLocalIp: true, // 使用本地Ip打开页面
overlay: true,// 编译发生错误时在浏览器窗口提示
after () { // 提供在服务器内部所有其他中间件之后执行自定义中间件的能力
console.log('\n 你的服务已启动: http://localhost:9000 \n Ctrl+C 结束')
}
},
plugins: [
new webpack.DefinePlugin({ // 定义环境和变量
'process.env': env
})
]
});
webpack.pro.config.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.base.config.js');
const env = require('../config/pro.conf.js')
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map', // 相比inline-source-map 性能好,不在包内部,体积小
plugins: [ // 压缩JS
new UglifyJSPlugin({
sourceMap: true
}),
new webpack.DefinePlugin({
'process.env': env
})
]
});
配置不同环境的驱动脚本:
package.json
"scripts": {
"build": "webpack --config build/webpack.pro.config.js",
"dev": "webpack-dev-server --progress --config build/webpack.dev.config.js"
},
值得注意的是:webpack-dev-server\webpack命令是在项目根目录下执行,配置中除了output的绝对路径,其他相对路径以根目录为基准
开发环境执行:
npm run dev
生产环境打包:
npm run build
启动之后正常运行,sourceMap可用
必要的配置:
一个必须的loader (babel-loader) 和 一个重要的插件 babel-polyfill,用来把新的ES6+语法,编译成浏览器识别的语法,详细用法看注释。
他们可以有效的解决
不识别箭头函数导致报错
IE下不识别Promise报错
现在这个项目已经越来越像vue-cli2了,只不过它把更多的配置又单独提到一个模块了,它有更多的插件、loader
vue-cli3更是把这些配置移植到了一些单独的项目,提供一个vue.config.js,合并进去来自定义一些配置
链接:https://pan.baidu.com/s/1Wu5XP192FcPvIQTiJuP1mg
提取码:0dzt