[ webpack4 ] 配置属于自己的打包系统教程(最终篇)—— 环境配置篇
GitHub 完整配置文件地址: https://github.com/yhtx1997/w...
由于篇幅过长分三次发布,建议按顺序看
[ webpack4 ] 配置属于自己的打包系统教程(一)—— 基础配置篇
[ webpack4 ] 配置属于自己的打包系统教程(二)—— 资源配置篇
[ webpack4 ] 配置属于自己的打包系统教程(最终篇)—— 环境配置篇
环境配置篇
主要内容
- 开发环境生产环境分离
- 实时预览
- webpack-dev-server 其他常用
- 代码复用处理
开发环境和生产环境
到了这一步,该讲讲开发环境模式和生产环境模式了
- 开发环境是自己开发时用的,需要有实时编译功能、模块热替换功能(更新文件不用完全更新页面)、错误提示到具体哪个文件几行
- 生产环境是放到线上给用户使用的,需要代码压缩功能
配置代码组件化
我们先把之前配置好的 webpack 配置文件改下名,改名 webpack.common.js ,意思是开发环境和生产环境都需要的,将代码压缩之类的挪到生产配置下
之后安装 webpack-merge ,官方推荐的是为每个环境写单独的 webpack 文件
虽然有简单的方法实现但是依然推荐写单独的配置文件,因为在这样的配置方式你可以更清楚你自己在做什么,还可以让你的配置更加个性(自定义)
安装 webpack-merge
npm install webpack-merge -D
新建开发环境配置
我们新建一个 js 文件,命名为 webpack.dev.js ,添加如下代码
const merge = require('webpack-merge');//合并配置 const common = require('./webpack.common.js');//引入公共配置 module.exports = merge(common, { mode: 'development',//声明是开发环境 //关于 dev 的配置 })
新建开发环境配置
我们新建一个 js 文件,命名为 webpack.prod.js
添加如下代码
const merge = require('webpack-merge');//合并配置 const UglifyJSPlugin = require('uglifyjs-webpack-plugin');//用来压缩 js 代码 const common = require('./webpack.common.js');//引入公共配置 module.exports = merge(common, { mode: 'production',//声明是生产环境 //关于 prod 的配置 });
开发环境
实时预览
跟着配置并操作的小伙伴可能发现了,每次修改后都需要手动在命令行输入命令,并且还要刷新浏览器才能看到最新的效果
那么现在来解决这两个问题,方法就是使用 webpack-dev-server
安装
npm install webpack-dev-server -D
配置
- 实时预览
- 自定义请求代理
- 自定义 ip 及端口
- 注:使用 webpack-dev-server 并不会编译到本地文件,而是放到内存中
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); const path = require('path'); const webpack = require('webpack'); module.exports = merge(common, { mode: 'development', devServer: { contentBase: path.join(__dirname, 'dist'),//预览的目录,写出口目录的绝对路径 hot: true,//模块热更新 host: 'localhost',//默认值 也可以改为 127.0.0.1 或者其他 port: 8080, proxy: { '/api': 'http://localhost:3000'//请求到 /api/users 现在会被代理到请求 http://localhost:3000/api/users } } })
接下来加入错误提示以及将生成 HTML 的代码从公共配置( webpack.common.js )拿到这里
因为开发和生产有些许不一样,我又不知道怎样简单配置,所以开发环境和生产环境我都会放一个生成 HTML 的代码
生产环境
- 每次打包都要清理掉旧文件
- 所有代码都要进行压缩
- 重复的 js 代码,需要只有一个就好
文件清理
从公共配置( webpack.common.js )将之前文件清理的代码拿过来放到这里
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = merge(common, { mode: 'production', plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: '2048', template: './src/index.html', minify: true,//HTML 代码压缩 hash: true }), ], })
代码压缩
先安装压缩代码的插件
npm install uglifyjs-webpack-plugin -D npm install optimize-css-assets-webpack-plugin -D
- uglifyjs-webpack-plugin 是 js 压缩插件
- optimize-css-assets-webpack-plugin 是推荐和
const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
复用代码分离
假设需要使用 jQuery 来辅助开发,我在 a.js b.js 两个文件都引入了 jQuery ,将 a.js b.js 打包成 a.min.js b.min.js ,这时看他们的体积会比原来大很多,且 a 和 b 的代码中都包含完整的 jQuery 代码
为了解决这种情况,我们需要将 jQuery 这种复用的代码分离到单独的文件
在将环境设置为生产环境时默认开启了很多功能,其中 SplitChunksPlugin 就是用于避免重复依赖的
在我们不配置时 默认配置是这样的
optimization: { splitChunks: { chunks: 'async', minSize: 30000, minChunks: 1, } }
- chunks: 表示哪些代码需要优化,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为async 改成 all 支持所有的
- minSize: 这个文件最少是多少才去优化,默认为 30000 实际测试是文件大于 30 kb,在 31kb时开始优化
- minChunks: 最少引用几次才去优化,默认为1 实际测试为在只引用一次的情况不优化,只有大于它才优化
- 注: 还有其他属性个人感觉不常用就没写,了解更多可以看这里
最终代码汇总
最终公共配置 webpack.common.js 代码如下
const path = require('path'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: { 512:'./src/js/512.js', 1024:'./src/js/1024.js', 2048:'./src/js/2048.js', }, plugins: [ new MiniCssExtractPlugin({ filename: "css/[name].css" }) ], output: { filename: "js/[name].js", path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } }, { test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader', ] }, { test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] }, { test: /\.(csv|tsv)$/, use: [ 'csv-loader' ] }, { test: /\.xml$/, use: [ 'xml-loader' ] } ] }, }
最终开发环境 webpack.dev.js 代码如下
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = merge(common, { mode: 'development', plugins: [ new HtmlWebpackPlugin({ title: '2048', template: './src/index.html', minify: false, hash: true }) ], devtool: 'inline-source-map', devServer: { contentBase: path.join(__dirname, 'dist'), host: 'localhost', port: 8080, proxy: { '/api': 'http://localhost:3000' } } })
最终生产环境 webpack.prod.js 代码如下
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = merge(common, { mode: 'production', plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: '2048', template: './src/index.html', minify: true, hash: true }), ], optimization: { splitChunks: { chunks: 'all' }, minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: true }), new OptimizeCSSAssetsPlugin({}) ], } });
npm 项目配置代码 package.json 代码如下
{ "name": "2048", "version": "1.0.0", "description": "", "private": true, "main": "index.js", "scripts": { "dev": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "webpack": "^4.28.3" }, "devDependencies": { "@babel/core": "^7.2.2", "@babel/preset-env": "^7.2.3", "autoprefixer": "^9.4.3", "babel-loader": "^8.0.4", "clean-webpack-plugin": "^1.0.0", "css-loader": "^2.1.0", "csv-loader": "^3.0.2", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "^3.0.1", "html-webpack-plugin": "^3.2.0", "mini-css-extract-plugin": "^0.5.0", "node-sass": "^4.11.0", "optimize-css-assets-webpack-plugin": "^5.0.1", "postcss": "^7.0.7", "postcss-loader": "^3.0.0", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "uglifyjs-webpack-plugin": "^2.1.1", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.14", "webpack-merge": "^4.1.5", "xml-loader": "^1.2.1" } }