一、webpack 配置详解之 entry
- 创建空文件夹,通过
npm init
命令初始化 package.json
文件,通过 npm install webpack webpack-cli -g
命令全局下载 webpack
和 webpack-cli
,通过 npm i html-webpack-plugin -D
命令下载 html-webpack-plugin
。 - 创建
src
文件夹,在里面创建 add.js
、count.js
和 index.js
文件,代码如下所示:
- add.js
function add(x, y) {
return x + y;
}
export default add;
- count.js
function count(x, y) {
return x - y;
}
export default count;
- index.js
import add from './add';
import count from './count';
console.log('index.js文件加载了~');
console.log(add(1, 2));
console.log(count(3, 2));
- 创建
webpack.config.js
文件,通过 require
引入 path
和 html-webpack-plugin
,entry
是入口文件,output
是出口文件,filename
是打包输出后的文件名,path
是输出路径。plugins
里面是一些插件配置,通过 new HtmlWebpackPlugin()
,复制里面的文件,并自动引入打包输出的所有资源(JS/CSS
),设置 mode
模式为 development
开发模式,代码如下所示:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
add: './src/add.js'
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development'
}
entry
是入口起点,分为三种类型,分别是 string
、array
和 object
,如下所示:
类型 | 类型描述 | 类型写法 |
---|
string | 单入口,打包形成一个chunk,输出一个bundle文件,此时chunk的名称默认是 main | './src/index.js' |
array | 多入口,所有入口文件最终只会形成一个chunk,输出出去只有一个bundle文件,只有在HMR功能中让html热更新生效 | ['./src/index.js', './src/add.js'] |
object | 多入口,有几个入口文件就形成几个chunk,输出几个bundle文件,此时chunk的名称是 key | {index:'./src/index.js', add: './src/add.js'} |
- 在命令行输入
webpack
命令,资源就会进行打包,同时在 bundle
文件夹中多出打包后的 index.js
、add.js
和 index.html
文件。
二、webpack 配置详解之 output
- 在上面的
entry
项目中,进行修改,修改 index.js
,代码如下所示:
import count from './count';
console.log('index.js文件加载了~');
import('./add').then(({ default: add }) => {
console.log(add(1, 2));
});
console.log(count(3, 2));
- 修改
webpack.config.js
文件,在 output
中,filename
是文件名称(指定名称+目录),path
是输出文件目录,将来所有资源输出的公共目录, publicPath
是所有资源引入公共路径前缀,chunkFilename
是非入口 chunk
的名称,library
是整个库向外暴露的变量名, 与 dll
结合某个库单独打包,代码如下所示:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].js',
path: resolve(__dirname, 'build'),
publicPath: '/',
chunkFilename: '[name]_chunk.js',
library: '[name]'
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development'
}
- 对于
output
中的 library
,类型如下所示:
类型 | 类型描述 |
---|
slibrary: '[name]' | 整个库向外暴露的变量名, 与 dll 结合某个库单独打包 |
libraryTarget: 'window' | 变量名添加到哪个上 browser |
libraryTarget: 'global' | 变量名添加到哪个上 node |
libraryTarget: 'commonjs' | 整体以 commonjs 的形式进行暴露 |
- 在命令行输入
webpack
命令,资源就会进行打包。
三、webpack 配置详解之 module
- 在上面的
output
项目中,进行修改,修改 webpack.config.js
文件。module
是 loader
的配置,rules
是详细的 loader
配置。第一个规则是匹配以 .css
结尾的文件,test
是匹配,use
是使用 loader
,使用 style-loader
和 css-loader
。第二个规则是匹配以 .js
结尾的文件,test
是匹配,exclude
是排除 node_modules
下的 js
文件,include
是只检查 src
下的 js
文件,enforce
为 pre
是优先执行,enforce
为 post
是延后执行,loader
是使用 eslint-loader
,单个 loader
用 loader
。第三个规则是使用 oneOf
,里面是数组,使用的 loader
及规则,并且里面的配置只会生效一个,代码如下所示:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
include: resolve(__dirname, 'src'),
enforce: 'pre',
loader: 'eslint-loader'
},
{
oneOf: []
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development'
}
- 在命令行输入
webpack
命令,资源就会进行打包。
四、webpack 配置详解之 resolve
- 在上面的
output
项目中,进行修改。修改 index.js
,同时新建 css
文件目录,里面创建 index.css
,代码如下所示:
- 修改
webpack.config.js
文件,resolve
是解析模块的规则,alias
是配置解析模块路径别名,优点是简写路径,缺点是路径没有提示。extensions
是配置省略文件路径的后缀名,modules
是告诉 webpack
解析模块是去找哪个目录,代码如下所示:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css/')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, './node_modules'), 'node_modules']
}
}
- 在命令行输入
webpack
命令,资源就会进行打包。
五、webpack 配置详解之 devServer
- 在上面的
resolve
项目中,进行修改,修改 webpack.config.js
文件。添加 devServer
,contentBase
是运行代码的目录,watchContentBase
是监视 contentBase
目录下的所有文件,一旦文件变化就会 reload
, watchOptions
中设置 ignored
是忽略监视的文件,compress
是启动 gzip
压缩,port
是端口号,host
是域名,open
是自动打开浏览器,hot
是开启 HMR
功能,clientLogLevel
是不要显示启动服务器日志信息,quiet
是除了一些基本启动信息以外,其他内容都不要显示, overlay
是如果出错了,不要全屏提示,proxy
是服务器代理去解决开发环境跨域问题,target
是目标路径,pathRewrite
是路径重写,代码如下所示:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css/')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, './node_modules'), 'node_modules']
},
devServer: {
contentBase: resolve(__dirname, 'build'),
watchContentBase: true,
watchOptions: {
ignored: /node_modules/
},
compress: true,
port: 5000,
host: 'localhost',
open: true,
hot: true,
clientLogLevel: 'none',
quiet: true,
overlay: false,
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: {
'^/api': ''
}
}
}
}
}
- 在命令行输入
npx webpack-dev-server
命令,资源就会进行打包。
六、webpack 配置详解之 optimization
- 在上面的
devServer
项目中,进行修改,修改 js
文件夹。在里面新增 a.js
,同时修改 index.js
,代码如下所示:
- a.js
export function add(x, y) {
return x + y;
}
- index.js
import('./a.js').then(({ add }) => {
console.log(add(1, 2));
});
- 修改
webpack.config.js
文件,通过 npm i terser-webpack-plugin -D
命令下载 terser-webpack-plugin
。添加 optimization
去优化提取代码,webpack4
中出现的,替代 webpack3
的 commonchunk
插件。添加 splitChunks
,设置 splitChunks
为 all
,说明是默认值,可以不写,如果想要修改,会在下面将详细的配置。runtimeChunk
是将当前模块的记录其他模块的 hash
单独打包为一个文件 runtime
,解决的是 修改 a
文件导致 b
文件的 contenthash
变化。在 minimizer
中,通过 TerserWebpackPlugin
配置生产环境的压缩方案 js
和 css
。cache
是开启缓存,parallel
是开启多进程打包,sourceMap
是启动 source-map
,代码如下所示:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build'),
chunkFilename: 'js/[name].[contenthash:10]_chunk.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css/')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, './node_modules'), 'node_modules']
},
devServer: {
contentBase: resolve(__dirname, 'build'),
watchContentBase: true,
watchOptions: {
ignored: /node_modules/
},
compress: true,
port: 5000,
host: 'localhost',
open: true,
hot: true,
clientLogLevel: 'none',
quiet: true,
overlay: false,
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: {
'^/api': ''
}
}
}
},
optimization: {
splitChunks: {
chunks: 'all'
},
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
},
minimizer: [
new TerserWebpackPlugin({
cache: true,
parallel: true,
sourceMap: true
})
]
}
}
splitChunks
中的配置,如下所示:
配置类型 | 类型描述 |
---|
minSize | 分割的chunk最小为 |
maxSize | 分割的chunk最大为 |
分割的chunk最小为 | 要提取的chunk最少被引用的次数 |
maxAsyncRequests | 按需加载时并行加载的文件的最大数量 |
maxInitialRequests | 入口js文件最大并行请求数量 |
automaticNameDelimiter | 名称连接符 |
name | 可以使用命名规则 |
cacheGroups | 分割chunk的组 |
- 在命令行输入
npx webpack-dev-server
命令,资源就会进行打包。