起步
之前我们使用webpack命令,只要安装webpack模块即可,现在还要再安装一个webpack-cli
先创建项目
npm init
安装webpack 和 webpack-cli
npm install webpack webpack-cli -D
零配置
根目录创建src文件,下面新增index.js文件,
针对比较简单的项目,webpack会去找src下面的index.js文件, 然后编译到dist
命令打包
npx webpack --mode development
mode主要控制压不压缩,默认不传,当值为production时,会压缩文件
基本配置
创建config文件,创建webpack.dev.js文件
入口配置、出口配置。需要注意的是:output里面的path必须是绝对路径
const path = require("path");module.exports = { entry: "./src/index.js", output: { filename: "bundle.js", path: path.join(__dirname, '../dist') } }
entry允许接受字符串,数组,对象
数组可以这么写,多个入口
对象的写法
修改packjson打包指令
image.png
直接输入命令
npm run build
报错了信息
当然解决很容易,只要用name(也就是entry里面的key)区别分文件名就行了:
const path = require('path')module.exports = { entry: { index:'./src/index.js', a:'./src/a.js' }, output: { filename: '[name].bundle.[hash:5].js', path: path.join(__dirname, '../dist') } }
也可以指定md5文件,写法如下:
filename: '[name].bundle.[hash:5].js',
:s表示截取5位
执行打包指令,生成
dev-server
不可能每次刷新页面都要重新打包的,最好内存帮我们编译好,实时刷新页面,故有了webpakc-dev-server模块
在根目录创建一个html文件,引入index.js
image.png
安装webpack-dev-server
sudo npm install webpack-dev-server -D
webpack.dev.js 添加devServer
devServer: { contentBase: path.resolve(__dirname,'../dist'), host:'localhost', compress:true, port:8888, }
package.json 添加指令
npm run server
本地部署服务
插件
列举一些常用的插件
clean-webpack-plugin
用来清理文件夹的,例如清理dist文件
HotModuleReplacementPlugin
这是webpack自带的,和devServer的hot参数配合使用。当然如果是配置在命令行--hot,则不需要加这个插件
html-webpack-plugin
在webpack配置中,我们可以将output的生成文件,加上md5,但这样一来,我们得手动改html文件,所以就有了html-webpack-plugin,它能够帮我们插入script及link标签。
purifycss-webpack
移除未使用的css
DefinePlugin
这也是webpack自身提供的插件。
比如我们有这个一个场景,测试环境用A地址,线上环境用B地址。那么我们就可以利用这个插件结合Node_ENV来实现,然后配多个scripts。
plugins: [ ..., new webpack.DefinePlugin({ __DEV__: process.env.NODE_ENV === 'development' }), ]
然后我们就可以在自己的业务代码中使用__DEV__
这个变量了。
extract-text-webpack-plugin
安装时,得npm install extract-text-webpack-plugin@next,因为4.0.0版本目前处于beta。
用来抽取css,这个插件用法会放在loder里面说明,因为这个代码得和loader一起使用才行。
copy-webpack-plugin
用来拷贝静态文件
BannerPlugin
webpack自带的一个插件,用来给代码添加版权信息
ProvidePlugin
webpack自带的一个插件,自动加载模块,而不必到处 import 或 require 。
plugins: [ ..., new webpack.ProvidePlugin({ $: 'jquery', }), ]
loader
wepack最最核心的就是,将所有的资源给转成js文件,这些是需要不同的loader来进行处理的,比如说css-loader、babel-loader、file-loader等
loader对象大概是长下面这样的:
有以下常见的key:
test (匹配规则)
use (数组,里面放一个个的loader,执行顺序从右到左)
exclude (排除什么文件夹)
css相关配置
以less为例的话,先要安装less、less-loader、css-loader、style-loader模块。
test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ] }
use数组中的每一项都可以改写成如下的形式:
{ loader: "style-loader", options: {} }
面几个loader的作用依次为:less-loader将代码转成css、css-loader用于解析(可以用来做css-moudle、压缩等)、style-loader则将解析后的样式嵌入js代码。
到了生产环境,我们不可能还是style的形式,通常都会抽成一个css。这个就得借助于上面提到的extract-text-webpack-plugin插件
module.exports = { mode: "development", entry: { ... }, output: { ... }, module: { rule: { { test: /\.less$/, use: ExtractTextWebpackPlugin.extract({ use: [ "css-loader", "less-loader" ] }) } } } devServer:{ ... }, plugins: [ ..., new ExtractTextWebpackPlugin({ filename: "css/index.css" }) ] }
注意上面没有style-loader了。
这样一来的话,就得写两个webpack配置了。如果想写成一个的话,就得写成这样的:
html-withimg-loader
这个是指在html文件中有用到某张图片,该图片有在入口文件中被引用。
具体配置如下:
{ test: /\.html/, use: 'html-withimg-loader'}, { test: /\.(png|gif|jpg)$/, use: [{ loader: 'url-loader', options: { limit: 5, outputPath: 'images/' } }] },
resolve
这个对象可以用来起别名、新增扩展后缀等功能。
module.exports = { mode: "development", entry: { ... }, output: { ... }, module: { ... }, resolve:{ // 别名 alias:{ '指定的名称':path.resolve(__dirname,'文件路径') }, // 省略后缀名 extensions:[' ','.js','.json','.css'], modules:['node_modules','lib'], //mainFields:['./a.js'] // 默认package.json的main是文件的入口 可以更改 }, devServer:{ ... }, plugins: [ ... ] }
抽取公共代码
module.exports = { mode: "development", entry: { ... }, output: { ... }, module: { ... }, optimization:{ splitChunks:{ cacheGroups:{ commons: { chunks: 'initial', name: 'commons', minChunks: 2, maxInitialRequests: 5, minSize: 0 }, vendor:{ // 抽离第三插件 test:/node_modules/, chunks:'initial', name:'vendor', priority:10 } } } }, resolve:{ ... }, devServer:{ ... }, plugins: [ ... ] }
当然这样改了之后,下面的htmlPlugin里面也要加上这两个才行:
在掘金上有一篇文章是关于这个参数讲解的,大家可以看看:webpack4.0打包优化策略(三)
在webpack3的时候,我依旧记得有一个bug,对Webpack的hash稳定性的初步探索,就是业务改了之后,vendor.js的hash值也会变化。
然后上面的方式,我测试了是OK了,也就是说不需要再加入HashedModuleIdsPlugin
。
结语
由于时间匆忙,整理的有点乱,希望大家有好的意见多多提议! 谢谢
作者:水落斜阳
链接:https://www.jianshu.com/p/71b61fc83ecc