0
点赞
收藏
分享

微信扫一扫

Webpack(二十四):总结


webpack 基本配置

搭建准备

  • ​$ npm init -y​
  • 创建​​package.json​
  • ​$ npm install webpack webpack-cli --save-dev​
  • 安装基础依赖
  • ​$ npm i webpack-dev-server --save-dev​
  • 配置开发环境的运行
  • ​创建 webpack.config.js 配置文件​
  • 构建webpack运行的默认配置文件
  • ​$ npm i html-loader html-webpack-plugin --save-dev​
  • 生成一个HTML文件作为站点入口

基础运行配置

  • 目录结构

.
├── public
│ └── index.html ## html模版文件
├── src
│ ├── asset ## 资源文件
│ └── main.js ## webpack入口文件
├── package.json ## npm init
└── webpack.config.js ## webpack默认配置文件

  • webpack.config.js

const {resolve} = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

/* 入口 */
entry: [
resolve(__dirname, 'src/main.js'),
],

/* 插件 */
plugins: [

/* 生成一个HTML文件作为站点入口 */
new HtmlWebpackPlugin({
template: resolve(__dirname, 'public/index.html'), // 模版html
}),

],

/* 模式 development || production */
mode: "development",

/* 开发环境服务 npx webpack-dev-server */
devServer: {
/* 内容地址 */
contentBase: resolve(__dirname, 'dist'),
/* 启动gzip压缩 */
compress: true,
/* 站点的端口号 */
port: 3000,
/* 执行后自动打开浏览器 */
open: true,
}

};

打包样式资源

  • ​$ npm i style-loader css-loader less less-loader --save-dev​

module.exports = {

/* 配置loader */
module: {

/* 规则配置 默认从数组尾向前进行处理 */
rules: [

/* 处理css文件 style-loader, css-loader */
{test: /\.css$/, use: ['style-loader', 'css-loader']},

/* 处理less文件 style-loader, css-loader, less-loader */
{test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},

],

}

}

每次构建清空打包后目录文件夹

​$ npm i clean-webpack-plugin --save-dev​

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {

plugins: [

/* 每次构建清空打包后目录文件夹 */
new CleanWebpackPlugin(),

]

}

webpack 之 entry

entry 三种格式

​entry : String​​ --> 单入口模式 (打包会生成一个chunk,输出一个bundle文件)

module.exports = {
entry: './src/main.js'
}

​entry : Array​​​ --> 多入口模式 (所有入口文件最终只会形成一个chunk,输出一个bundle文件)
一般会将html文件放入,使开发环境的HMR配置生效

module.exports = {
entry: [ './src/main.js', './public/index.html', ],
}

​entry : Object​​ --> 多入口模式 (有几个入口文件最终就会形成几个chunk,chunk名称为key,同时也会输出几个bundle文件)

module.exports = {
entry: {
main: './src/main.js',
demo: './src/views/demo.js',
}
}

​entry : Object[Array]​​ --> 多入口模式 (数组部分打包成一个chunk,字符串部分打包成一个chunk)

.exports = {
entry: {
main: [ './src/main.js', './src/views/index.js' ],
demo: './src/views/demo.js',
}
}

webpack 之 output

output 配置输出文件常用配置

module.exports = {

/* 出口 */
output: {

/* 构建输出地址 绝对路径 */
path: resolve(__dirname, 'dist'),

/* 构建输出文件名称 注意:配置热更新hot后启动服务将无法使用contenthash作为文件名 */
filename: this.mode === 'production' ? 'js/[name].[contenthash:10].js' : 'js/[name].[hash:10].js',

/* 输出文件路径定义 一般用于生产环境 */
publicPath: '/',

/* 对非入口文件chunk创建名称 js代码采用import('./xxx/xxx.js').then().catch(); */
chunkFilename: 'js/[name]_chunk.js',

/* 将value作为打包后的全局变量暴露出来,默认用var定义 示例:var main = (function(modules) {···})({···}) */
library: '[name]',

/* 设置后默认值 var , 实现通过哪种(var, commonjs, window, global)方式定义暴露的变量 */
libraryTarget: 'var', // var commonjs window global

},

}

webpack 之 module

module 配置loader常用配置

module.exports = {
/* 配置loader */
module: {

/* loader配置 默认从数组尾向前进行处理 */
rules: [

/* 处理css文件 style-loader, css-loader */
{test: /\.css$/, use: ['style-loader', 'css-loader']},

/* 处理less文件 style-loader, css-loader, less-loader */
{test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},

/* 处理html文件 html-loader 将 HTML 导出为字符串。当编译器需要时,将压缩 HTML 字符串 */
{test: /\.html$/, loader: 'html-loader'},

],

},
}

webapck 之 resolve

resolve --> alias: 解决引用文件时需要多层引入问题

  • 比如引用css文件:​​import '../../../../xxx/xxx/xxx.css';​

/* main.js */
import '$css/common.css';
import '$css/demo.less';

/* webpack.config.js */
module.exports = {

/* 解析模块的规则 */
resolve: {

/* 配置解析模块路径别名 */
alias: {
$css: resolve(__dirname, 'src/assets/css')
}

}

}

resolve --> extensions: 配置省略文件路径后缀名

/* main.js */
import './css/xxx'; // 省略 .css
import './json/xxx'; // 省略 .json
import './js/xxx'; // 省略 .js

/* webpack.config.js */
module.exports = {

/* 解析模块的规则 */
resolve: {

/* 配置省略文件路径后缀名 (先会去查找.js文件,有就返回,没有继续向后查找) */
extensions: [ '.js', '.json', '.css']

}

}

resolve --> modules: 配置解析模块(node_modules)寻找地址

module.exports = {
/* 解析模块的规则 */
resolve: {
/* 配置解析模块(node_modules)寻找地址 (默认在webpack.config.js所在目录向上寻找) */
modules: [ resolve(__dirname, 'node_modules'), 'node_modules' ], // 数组[1]预防之前配置寻找不到node_modules而配置

}
}

webpack 之 devServer

devServer 用于开发环境

module.exports = {
/* npx webpack-dev-server */
devServer: {
/* 内容地址 */
contentBase: resolve(__dirname, 'dist'),
/* 监视 contentBase 下的所有文件,一旦文件产生变化就会reload刷新 */
watchContentBase: true,
/* 监视配置 */
watchOptions: {
/* 忽略 node_modules 下文件 */
ignored: /node_modules/
},
/* 启动gzip压缩 */
compress: true,
/* 站点的端口号 */
port: 3000,
/* 域名 */
host: 'localhost',
/* 执行后自动打开浏览器 */
open: true,
/* 热更新 */
hot: true,
/* 不需要打印启动程序时的日志信息 */
clientLogLevel: false,
/* 除了一些基本启动信息以外,其他内容不需要打印 */
quiet: true,
/* 如果出错了,不需要全屏提示 */
overlay: false,
/* 服务器代理 --> 解决开发环境跨域问题 */
proxy: {
/* 接收到/api/xxx的请求后,会将请求转发到http://localhost:3000这个地址下,从而解决跨域 */
'/api': {
target: 'http://localhost:3000',
/* 路径重写 将请求路径 /api/xxx 改写成 /xxx (去掉 /api ) */
pathRewrite: {
'^/api': ''
}
}
}
},
}

webpack 之 optimization

splitChunks 默认配置

module.exports = {
mode: 'production',
/* 优化 mode: 'production' */
optimization: {
/* chunk分割 */
splitChunks: {
chunks: 'all',
/* ========================以下为默认配置项,可以不写========================= */
/* 分割的chunk最小为30kb */
minSize: 30 * 1024,
/* 分割的chunk最大无限制 */
maxSize: 0,
/* 提取的chunk最少被引用1次 */
minChunks: 1,
/* 按需加载时并行加载的文件最大数量 */
maxAsyncRequests: 5,
/* 入口js文件最大并行请求数量 */
maxInitialRequests: 3,
/* 名称连接符 */
automaticNameDelimiter: '~',
/* 可以使用命名规则 */
name: true,
/* 分割chunk的组 */
cacheGroups: {
/* node_modules中的文件会被打包到vendors组的chunk中, 名称:vendors~xxx.js */
vendors: {
test: /[\\/]node_modules[\\/]/,
/* 优先级 */
priority: -10,
},
default: {
/* 提取的chunk最少被引用2次 */
minChunks: 2,
priority: -20,
/* 如果当前要打包的模块和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块,比如都引入了jQuery */
reuseExistingChunk: true,
}
}
}
}
}

splitChunks 默认配置 出现的问题

// main.js
import(/* webpackChunkName: 'index' */ './views/index')
.then(res=>{
console.log(res);
})
.catch(err=>{
console.log(err);
});

// index.js
console.log('Index Js');
// => 修改为
// console.log('Index Js ABC');

// webpack.config.js
module.exports = {
mode: 'production',
/* 优化 mode: 'production' */
optimization: {
/* chunk分割 */
splitChunks: {
chunks: 'all',
}
}
}

当其中index.js的代码进行修改后,
预期希望打包后只有index.js的文件名发生变化,不会影响到main.js的缓存机制,
但是由于main.js代码内部存储了index.js文件的hash值,
最终导致index.js被修改后再次打包main.js和index.js的文件名都发生了变化,
导致main.js文件没有从缓存中读取,又请求了一次,影响性能

Webpack(二十四):总结_json

以上问题解决方法

希望提取出main.js中引用的index.js的hash值在进行单独处理

// webpack.config.js
module.exports = {
mode: 'production',
/* 优化 mode: 'production' */
optimization: {
/* chunk分割 */
splitChunks: {
chunks: 'all',
}
},
/* 将当前模块记录的其他模块的hash值单独打包成一个文件 runtime */
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
}
}

Webpack(二十四):总结_webpack_02

minimizer 配置生产环境的压缩方案 js和css方案

  • 需要安装:​​$ npm i terser-webpack-plugin --save-dev​

const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
/* 配置生产环境的压缩方案 js和css方案 */
minimizer: [
new TerserPlugin({
/* 开启缓存 */
cache: true,
/* 开启多进程打包 */
parallel: true,
/* 启用 source-map */
sourceMap: true,
}),
]
}
}

完整代码

Webpack(二十四):总结_css_03

npm i html-loader --save-dev
npm i terser-webpack-plugin --save-dev
npm i clean-webpack-plugin --save-dev
npm i style-loader css-loader less less-loader --save-dev
npm i html-webpack-plugin --save-dev
npm i webpack-dev-server --save-dev
npm

{
"name": "javascriptdesignpatterns",
"version": "1.0.0",
"description": "设计模式",
"main": "index.js",
"scripts": {
"dev": "npx webpack-dev-server",
"build": "webpack"
},
"author": "ProsperLee",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^4.3.0",
"html-loader": "^1.3.2",
"html-webpack-plugin": "^4.5.0",
"less": "^3.12.2",
"less-loader": "^7.0.2",
"style-loader": "^2.0.0",
"terser-webpack-plugin": "^4.2.3",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
}

// webpack.config.js
const {resolve} = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {

/* 入口 */
entry: [

'./src/main.js',

'./public/index.html',

],

/* 出口 */
output: {

/* 构建输出地址 绝对路径 */
path: resolve(__dirname, 'dist'),

/* 构建输出文件名称 注意:配置热更新hot后启动服务将无法使用contenthash作为文件名 */
filename: this.mode === 'production' ? 'js/[name].[contenthash:10].js' : 'js/[name].[hash:10].js',

/* 输出文件路径定义 一般用于生产环境 */
publicPath: '/',

/* 对非入口文件chunk创建名称 */
chunkFilename: 'js/[name].[contenthash:10]_chunk.js',

/* 将value作为打包后的全局变量暴露出来,默认用var定义 示例:var main = (function(modules) {···})({···}) */
library: '[name]',

/* 设置后默认值 var , 实现通过哪种(var, commonjs, window, global)方式定义暴露的变量 */
libraryTarget: 'var', // var commonjs window global

},

/* 配置loader */
module: {

/* loader配置 默认从数组尾向前进行处理 */
rules: [

/* 处理css文件 style-loader, css-loader */
{test: /\.css$/, use: ['style-loader', 'css-loader']},

/* 处理less文件 style-loader, css-loader, less-loader */
{test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},

/* 处理html文件 html-loader 将 HTML 导出为字符串。当编译器需要时,将压缩 HTML 字符串 */
{test: /\.html$/, loader: 'html-loader'},

],

},

/* 插件 */
plugins: [

/* 每次构建清空打包后目录文件夹 */
new CleanWebpackPlugin(),

/* 生成一个HTML文件作为站点入口 */
new HtmlWebpackPlugin({
template: resolve(__dirname, 'public/index.html'), // 模版html
minify: true, // 是否压缩
}),

],

/* 模式 development || production */
mode: 'development',

/* npx webpack-dev-server */
devServer: {
/* 内容地址 */
contentBase: resolve(__dirname, 'dist'),
/* 监视 contentBase 下的所有文件,一旦文件产生变化就会reload刷新 */
watchContentBase: true,
/* 监视配置 */
watchOptions: {
/* 忽略 node_modules 下文件 */
ignored: /node_modules/
},
/* 启动gzip压缩 */
compress: true,
/* 站点的端口号 */
port: 3000,
/* 域名 */
host: 'localhost',
/* 执行后自动打开浏览器 */
open: true,
/* 热更新 */
hot: true,
/* 不需要打印启动程序时的日志信息 */
clientLogLevel: false,
/* 除了一些基本启动信息以外,其他内容不需要打印 */
quiet: true,
/* 如果出错了,不需要全屏提示 */
overlay: false,
/* 服务器代理 --> 解决开发环境跨域问题 */
proxy: {
/* 接收到/api/xxx的请求后,会将请求转发到http://localhost:3000这个地址下,从而解决跨域 */
'/api': {
target: 'http://localhost:3000',
/* 路径重写 将请求路径 /api/xxx 改写成 /xxx (去掉 /api ) */
pathRewrite: {
'^/api': ''
}
}
}
},

/* 开启调试功能 */
devtool: 'eval-source-map',

/* 解析模块的规则 */
resolve: {

/* 配置解析模块路径别名 */
alias: {
$css: resolve(__dirname, 'src/assets/css')
},

/* 配置省略文件路径后缀名 (先会去查找.js文件,有就返回,没有继续向后查找) */
extensions: [ '.js', '.json', '.css'],

/* 配置解析模块(node_modules)寻找地址 (默认在webpack.config.js所在目录向上寻找) */
modules: [ resolve(__dirname, 'node_modules'), 'node_modules' ], // 数组[1]预防之前配置寻找不到node_modules而配置

},

/* 优化 mode: 'production' */
optimization: {

/* chunk分割 */
splitChunks: {
chunks: 'all',
// /* 分割的chunk最小为30kb */
// minSize: 30 * 1024,
// /* 分割的chunk最大无限制 */
// maxSize: 0,
// /* 提取的chunk最少被引用1次 */
// minChunks: 1,
// /* 按需加载时并行加载的文件最大数量 */
// maxAsyncRequests: 5,
// /* 入口js文件最大并行请求数量 */
// maxInitialRequests: 3,
// /* 名称连接符 */
// automaticNameDelimiter: '~',
// /* 可以使用命名规则 */
// name: true,
// /* 分割chunk的组 */
// cacheGroups: {
// /* node_modules中的文件会被打包到vendors组的chunk中, 名称:vendors~xxx.js */
// vendors: {
// test: /[\\/]node_modules[\\/]/,
// /* 优先级 */
// priority: -10,
// },
// default: {
// /* 提取的chunk最少被引用2次 */
// minChunks: 2,
// priority: -20,
// /* 如果当前要打包的模块和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块,比如都引入了jQuery */
// reuseExistingChunk: true,
// }
// }
},

/* 将当前模块记录的其他模块的hash值单独打包成一个文件 runtime */
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
},

/* 配置生产环境的压缩方案 js和css方案 */
minimizer: [
new TerserPlugin({
/* 开启缓存 */
cache: true,
/* 开启多进程打包 */
parallel: true,
/* 启用 source-map */
sourceMap: true,
}),
],

}

};


举报

相关推荐

0 条评论