Webpack配置
1. mode:模式
-
development:开发模式
启用
NamedChunksPlugin
和NamedModulesPlugin
。NamedChunksPlugin:把chunk id变为一个字符串标识符。
NamedModulesPlugin:当开启 HMR 的时候使用该插件会显示模块的相对路径,建议用于开发环境。
-
production:生产模式
启用
FlagDependencyUsagePlugin
,FlagIncludedChunksPlugin
,ModuleConcatenationPlugin
,NoEmitOnErrorsPlugin
,OccurrenceOrderPlugin
,SideEffectsFlagPlugin
和UglifyJsPlugin
。FlagDependencyUsagePlugin:
FlagIncludedChunksPlugin:
ModuleConcatenationPlugin
NoEmitOnErrorsPlugin
OccurrenceOrderPlugin
SideEffectsFlagPlugin
UglifyJsPlugin
none:不开启任何插件
2. entry:入口
entry配置的多种形式:字符串、数组、对象、函数。
2.1 字符串
module.exports = {
entry: './src/index.js'
}
2.2 数组
作用:将多个资源预先合并,在打包时将数组中最后一个元素作为实际入口路径。
module.exports = {
entry: ['babel-polyfill', './src/index.js']
}
2.3 对象
多入口文件配置
module.exports = {
entry: {
page1: './src/page1.js',
page2: './src/page2.js'
}
}
2.4 函数
module.exports = {
entry: () => './src/index.js'
}
module.exports = {
entry: () => ({
// 添加一些动态逻辑获取工程的入口
if (boolean) {
return './src/index.js'
} else {
return './src/main.jss'
}
// 或者
// 返回一个Promise对象进行异步操作
return new Promise(resolve => resolve('./src/index.js'));
})
}
注意:
- Webpack默认,bundle.js文件大于250KB(压缩前)会认为文件过大,会发生警告。
- 通过多入口将vendor(包含库,框架等第三方不常用模块打包产生的bundle)打包,提升效率
- 配置多页应用,减少资源体积。
3. output:资源出口
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'assets'),
publicPath: '/dist/'
}
}
output的配置项:
3.1 filename
控制输出资源的文件名
bundle.js: 设置为固定的文件名
[name].js: entry设置为对象的key值(上述2.3的page1.js和page2.js)
[hash].js: 当前打包的所有资源的hash
[chunkhash].js: 当前chunk内容的hash
[id]: 当前chunk的ID
[query]: filename配置项中的query
注意:
- 开发环境不必要设置chunkhash,强烈推荐生产环境配置chunkhash,目的是控制客户端缓存。
3.2 path
指定资源输出的位置,必须为绝对路径(默认为dist目录)。
{
path: path.join(__dirname, 'dist') // build构建后资源存储的位置
}
注意:
- Webpack-dev-server 也有publicPath参数,请设置该参数和webpack的path路径相同。
3.3 publicPath:
由JS或CSS内部请求的间接资源(异步加载的CSS,CSS请求图片、字体等)的请求位置。
当前html请求路径为:https://weixin.dongyin.net/coach/index.html
打包之后异步资源为chunk-a3b82d.js文件
1. 相对路径:以构建之后的html为基准,获取页面资源的相对路径(请求地址如果为https://www.test.com)
{
publicPath: '' // 请求地址为:https://weixin.dongyin.net/coach/chunk-a3b82d.js
publicPath: './js' // 请求地址:https://www.test.com/coach/js/chunk-a3b82d.js
publicPath: '../assets' // 请求地址:https://www.test.com/assets/chunk-a3b82d.js
}
2. Host相关
{
publicPath: '/' // 请求地址为:https://weixin.dongyin.net/chunk-a3b82d.js
publicPath: '/js' // 请求地址:https://www.test.com/coach/js/chunk-a3b82d.js
publicPath: '/dist' // 请求地址:https://www.test.com/coach/dist/chunk-a3b82d.js
}
3. CDN相关
{
publicPath: 'https://cdn.com' // 请求地址为:https://cdn.com/chunk-a3b82d.js
publicPath: '//cdn.com/app' // 请求地址为://cdn.com/app/chunk-a3b82d.js
}
4. Module
两个配置:
4.1 noParse
对指定的内容不解析:noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/
4.2 rules
一个web工程通常包含HTML、JS、CSS、模版、图片、字体、SVG等多种类型的静态资源,资源之间又存在着某种联系。
对于Webpack来说,这些静态资源都是模块,我们可以加载一个JS文件一样去加载他们,但是JS又确实不认识他们,于是有了Loader辅助webpack,认识各种各样的资源文件。
原理:
- 每个loader本身就是一个函数
- webpack4之前,函数输入和输出都是字符串
- webpack4之后,函数输入和输出支持抽象语法树(AST),目的减少重复代码解析
- webpack先对代码解析=>由每一个loader对解析结果进行一一处理=>处理完成,交给webpack继续处理
4.3 常用loader
{
// 正则表达式,匹配成功的模块使用该规则
test: /\.css$/,
// string|array: 使用的loader
use: 'raw-loader',
// 排除指定目录下的模块
exclude: /node_modules/,
// 包含指定目录下的模块
include: /src/,
// 只有src/pages下的js文件加载css
issuer: {
test: '/\.js$/',
include: /src/pages
},
// 强制该loader在所有loader之前执行,避免被其他loader更改过(比如:eslint-loader需要先执行)
enforce: 'pre'
}
1. exclude和include同时存在且不冲突,取并集
2. exclude和include同时存在有冲突,exclude优先级高
1. raw-loader
raw-loader
解析文本文件(比如.txt后缀但不局限于.txt的文件)
{
test: /\.txt$/,
use: 'raw-loader'
}
2. 样式loader集合
sass-loader
解析sass/scss样式(sass-loader起连接作用,主要是node-sass解析sass/scss内容)
css-loader
解析css后缀的文件,解析结果返回字符串。
vue-style-loadere
基于 style-loader
,被 vue-loader
依赖
style-loader
将 css-loader
的解析结果(字符串)以内联标签<style>形式插入到 <head> 标签内。
postcss
编译插件的容器,将接收的样式源代码交由编译插件处理,最后输出css。
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
{
test: /\.scss$/,
use: [
/* config.module.rule('sass').oneOf('normal') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('scss').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('scss').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('scss').oneOf('normal').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false,
data: '@import "@/scss/_variables.scss";@import "@/scss/_mixins.scss";'
}
}
]
}
注意:
webpack打包的时候按照数组从后往前的顺序将资源交给loader处理,因为最后生效的
style-loader
放前面。-
关于PostCSS的处理
postcss-loader
将PostCSS与Webpack连接,在根目录下创建postcss.config.js
.Autoprefixer:根据caniuse.com的数据,决定是否给css增加前缀
stylelint: CSS 代码质量检测工具(语法错误,重复属性)
CSSNext:使用最新的CSS语法特性
-
CSS Module:CSS模块化
- 每个CSS文件中的样式拥有单独的作用域,不会和外界发生命名冲突。
- 对CSS进行依赖管理,可以通过相对路径引入CSS文件
- 通过compose轻松复用其他CSS模块
{ test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: true, localIdentName: '[name]__[local]__[hash:base64:5]' } } ] }
postcss.config.js内容
const autoprefixer = require('autoprefixer');
const stylelint = require('stylelint');
module.exports = {
plugins: [
autoprefixer({
grid: true,
browsers: ['> 1%', 'last 3 versions', 'android 4.2', 'ie 8']
}),
stylelint({
config: {
rules: {
'declaration-no-important': true
}
}
})
]
}
3. babel-loader
babel-loader
处理ES6+编译为ES5。
与此同时,还需要下载几个包:
babel-loader
:Babel与Webpack协同工作的模块(起连接作用)。
@babel/core
:Babel编译器的核心模块。
@babel/preset-env
:Babel官方推荐的预置器,可根据用户设置的目标环境自动添加所需的插件和补丁编译ES6+代码。
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
preset: [
['env', { module: false }]
]
}
}
}
注意:
1. babel-loader 对所有JS后缀文件设置规则,需要在exclude中添加node_modules,提升打包速度。
2. 使用cacheDirectory配置,启用缓存机制,避免未改变过的模块二次编译。
3. @babel/preset-env 将ES6 Module转化为CommonJS,导致Webpack的tree-shaking特性失效,将modules设置为false,禁用模块语句转化,将ES6 Module的语法交给Webpack本身处理。
4. babel-loader 支持从.babelrc文件读取babel配置,将presets和plugins从webpack配置文件读取出来,达到同样效果。
4. file-loader
file-loader
用于处理打包文件类型的资源,返回其publicPath。
{
test: /\.(png|jpe?g|gif|webp)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'static/img/[name].[hash:8].[ext]',
publicPath: './otherPath/' // 覆盖webpack.output.publicPath
}
}
]
}
注意:
1. 如果没有设置webpack的output的publicPath值,返回 文件名
2. 如果设置webpack的output的publicPath值,返回 webpack.output.publicPath+文件名
5. url-loader
url-loader
与 file-loader
功能类似,但是可以 设置阈值,小于该阈值则返回对应文件的base64编码。
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'static/img/[name].[hash:8].[ext]'
}
}
}
}
]
}
注意:
1. 设置了limit属性,值为4096,当图片大小超过4kb的时候,会被转为base64的格式
6. vue-loader
vue-loader
处理vue组件。
但是,还需要
vue-template-compiler
编译Vue模版
sass-loader
处理sass/scss
css-loader
处理css样式
{
test: /\.vue$/,
use: 'vue-loader'
}
5. Plugins
5.1 VueLoaderPlugin
Vue-loader必须配合VueLoaderPlugin插件才能正常工作。
5.2 DefinePlugin
创建一个在编译时可以配置的全局常量
5.3 HotModuleReplacementPlugin
模块热替换插件