三. webpack开发环境配置
开发环境配置主要是为了能让代码运行。主要考虑以下几个方面:
- 打包样式资源
- 将css/less资源打包到style标签
- 打包 html 资源
- 打包图片,字体等其他静态资源
- devServer
3.1打包css资源
安装npm i css-loader style-loader -D```javascript const { resolve } = require(‘path’)
module.exports = { mode: “development”, // mode: “production”, entry: “./src/index”, output: { filename: ‘built.js’, path: resolve(__dirname, “build”) }, // 配置模块 module: { // 指定规则 rules: [ { test: /.css$/, // 加载顺序,从下到上,从右到左 use: [ // style-loader:创建style标签,将js中的样式资源插入进去,添加到head中生效 ‘style-loader’, // css-loader:将css文件变成commonjs模块加载到js中,里面内容是样式字符串 ‘css-loader’ ] } ] } }
<a name="e4iup"></a>## 3.2打包less资源安装 `npm i less-loader -D````javascriptconst { resolve } = require('path')module.exports = {mode: "development",// mode: "production",entry: "./src/index",output: {filename: 'built.js',path: resolve(__dirname, "build")},// 配置模块module: {// 指定规则rules: [{test: /\.css$/,// 加载顺序,从下到上,从右到左use: [// style-loader:创建style标签,将js中的样式资源插入进去,添加到head中生效'style-loader',// css-loader:将css文件变成commonjs模块加载到js中,里面内容是样式字符串'css-loader',]},{test: /\.less$/,use: ['style-loader','css-loader',// less-loader:将less文件编译成css文件,需要下载less-loader和less'less-loader']}]}}
3.3打包html资源
- html-webpack-plugin
- 在build文件夹中生成html文件,并自动引入相应资源
- 指定html模板,设置html变量,指定html名称
- 指定模板:
template:'./src/index.html' - 设置变量:
title:"黄显瑜你可真是个小天才"(不常用)- 接收变量:
<%= htmlWebpackPlugin.options.title %>
- 接收变量:
- 指定名称:
filename:'index_online.html'
- 指定模板:
- 安装
npm i html-webpack-plugin -D - 引入插件
const htmlWebpackPlugin = require('html-webpack-plugin')```javascript const { resolve } = require(‘path’) const miniCssExtractPlugin = require(‘mini-css-extract-plugin’) const htmlWebpackPlugin = require(‘html-webpack-plugin’)
module.exports = { mode: “development”, // mode: “production”, entry: “./src/index”, output: { filename: ‘built.js’, path: resolve(__dirname, “build”) }, // 配置模块 module: { // 指定规则 rules: [ { test: /.css$/, // 加载顺序,从下到上,从右到左 use: [ miniCssExtractPlugin.loader, // css-loader:将css文件变成commonjs模块加载到js中,里面内容是样式字符串 ‘css-loader’, ] }, { test: /.less$/, use: [ miniCssExtractPlugin.loader, ‘css-loader’, // less-loader:将less文件编译成css文件,需要下载less-loader和less ‘less-loader’ ] } ] }, plugins: [ new miniCssExtractPlugin({ filename:’css/other.css’ }), // 压缩html new htmlWebpackPlugin({ // 指定html模板 template:’./src/index.html’,
// 指定名称
filename:'index_online.html',
// 指定变量(不建议将数据写到配置文件中)
title:"黄显瑜你可真是个小天才"
})
]
}
<a name="Y8Cgf"></a>
## 3.4资源处理 asset-modules
webpack5使用新增的四种资源模块(Asset Modules)代替了url-loader,file-loader,raw-loader的功能
<a name="L3vSf"></a>
### 3.4.1 asset/resource
将资源分割为**单独的文件**,并导出url,就是之前的file-loader的功能<br />
<a name="O22Fz"></a>
### 3.4.2 asset/inline
将资源导出为dateURL(url(data:))的形式,,之前的url-loader的功能<br />
<a name="8mM7k"></a>
### 3.4.3 asset/source
将资源导出为源码(source code),之前的raw-loader功能
<a name="8GIns"></a>
### 3.4.4 asset
自动选择导出为单独文件或者dataURL形式(默认为8KB),之前有url-loader设置 limit 限制实现
<a name="yinlb"></a>
### 3.4.5 资源处理配置文件
```javascript
const { resolve } = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
entry: './src/index',
output: {
filename: 'built.js',
path: resolve(__dirname, "build"),
// 自定义模块输出的位置和名字
// assetModuleFilename: 'images/[hash][ext][query]'
},
// 配置模块
module: {
// 指定规则
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|jpg)$/,
// 指定资源打包的类型
type: 'asset/resource',
// 指定资源打包后输出的位置和名字
generator:{
filename:'imgs/[name]-[hash:5][ext]'
}
},
{
test: /\.(ttf|woff|woff2)$/,
// 指定资源打包的类型
type: 'asset/inline'
},
{
test: /\.txt$/,
// 指定资源打包的类型
type: 'asset',
// 设置限制来判断资源应该单独分割为一个文件,还是导出为dateURL(url(data:))的形式
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
}
]
},
plugins: [
new htmlWebpackPlugin({
template: './src/index.html',
})
]
}
3.5 dev server服务器
提供自动化web服务(自动编译,自动打开浏览器,自动刷新浏览器)
特点:只会在内存中编译打包,不会有任何输出
安装: npm i webpack-dev-server -g
启动命令: webpack server
安装: npm i webpack-dev-server -D
启动命令: npx webpack server
文档: https://webpack.docschina.org/configuration/dev-server/
const { resolve } = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/index',
output: {
filename: 'built.js',
path: resolve(__dirname, "build"),
// 自定义模块输出的位置和名字
// assetModuleFilename: 'images/[hash][ext][query]'
},
// 配置模块
module: {
// 指定规则
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|jpg)$/,
// 指定资源打包的类型
type: 'asset/resource',
// 指定资源打包后输出的位置和名字
generator:{
filename:'imgs/[name]-[hash:5][ext]'
}
},
{
test: /\.(ttf|woff|woff2)$/,
// 指定资源打包的类型
type: 'asset/inline'
},
{
test: /\.txt$/,
// 指定资源打包的类型
type: 'asset',
// 设置限制来判断资源应该单独分割为一个文件,还是导出为dateURL(url(data:))的形式
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
}
]
},
//
devServer:{
// 指定加载的目录的路径
contentBase:resolve(__dirname,'build'),
// 启动gzip压缩,让我们代码体积更小,启动更快
compress:true,
// 端口号
port:6789,
// 自动打开浏览器
open:true,
// 热更新
// 只在内存中打包
// 即,打包输出目录中并没有数据
liveReload:true
},
// 只适用于web相关的target
target:'web',
plugins: [
new htmlWebpackPlugin({
template: './src/index.html',
})
]
}
3.6开发环境的基本配置
安装 npm i -D css-loader style-loader less-loader html-webpack-plugin webpack-dev-server
// resolve用来拼接绝对路径的方法
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin') // 引用plugin
module.exports = {
// webpack配置
entry: './src/index.js', // 入口起点
output: {
// 输出
// 输出文件名
filename: 'js/build.js',
// __dirname是nodejs的变量,代表当前文件的目录绝对路径
path: resolve(__dirname, 'build'), // 输出路径,所有资源打包都会输出到这个文件夹下
},
// loader配置
module: {
rules: [
// 详细的loader配置
// 不同文件必须配置不同loader处理
{
// 匹配哪些文件
test: /\.less$/,
// 使用哪些loader进行处理
use: [
// use数组中loader执行顺序:从右到左,从下到上,依次执行
// style-loader:创建style标签,将js中的样式资源插入进去,添加到head中生效
'style-loader',
// css-loader:将css文件变成commonjs模块加载到js中,里面内容是样式字符串
'css-loader',
// less-loader:将less文件编译成css文件,需要下载less-loader和less
'less-loader'
],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: 'html-loader',
options: {
esModule: false
}
},
{
test: /\.(png|jpg|gif)$/,
// 指定资源打包的类型
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
// 指定资源打包后输出的位置和名字
generator:{
filename: 'imgs/[name].[hash:5][ext]'
}
},
// 打包其他资源(除了html/js/css/图片资源以外的资源)
{
test: /\.(ttf|woff|woff2)$/,
// 指定资源打包的类型
type: 'asset/resource',
generator:{
filename:'media/[name].[hash:5][ext]'
}
},
],
},
// plugin的配置
plugins: [
// html-webpack-plugin:默认会创建一个空的html文件,自动引入打包输出的所有资源(JS/CSS)
// 需要有结构的HTML文件可以加一个template
new HtmlWebpackPlugin({
// 复制这个./src/index.html文件,并自动引入打包输出的所有资源(JS/CSS)
template: './src/index.html',
}),
],
// 模式
mode: 'development', // 开发模式
// 开发服务器 devServer:用来自动化,不用每次修改后都重新输入webpack打包一遍(自动编译,自动打开浏览器,自动刷新浏览器)
// 特点:只会在内存中编译打包,不会有任何输出(不会像之前那样在外面看到打包输出的build包,而是在内存中,关闭后会自动删除)
devServer: {
// 指定加载的目录的路径
contentBase: resolve(__dirname, 'build'),
// 启动gzip压缩,让我们代码体积更小,启动更快
compress: true,
// 端口号
port: 6789,
// 自动打开浏览器
open: true,
// 热更新
// 只在内存中打包
// 即,打包输出目录中并没有数据
liveReload: true
},
// 只适用于web相关的target
target: 'web',
}
四. webpack生产环境配置
而生产环境的配置需要考虑以下几个方面:
- 提取 css 成单独文件
- css 兼容性处理
- 压缩 css
- js 语法检查
- js 兼容性处理
- js 压缩
-
4.1把css打包为单独的文件
安装
npm i mini-css-extract-plugin -D- 引入插件
const miniCssExtractPlugin = require('mini-css-extract-plugin') - 把 style-loader 替换为 miniCssExtractPlugin.loader ```javascript const { resolve } = require(‘path’) const miniCssExtractPlugin = require(‘mini-css-extract-plugin’)
module.exports = { mode: “development”, // mode: “production”, entry: “./src/index”, output: { filename: ‘built.js’, path: resolve(__dirname, “build”) }, // 配置模块 module: { // 指定规则 rules: [ { test: /.css$/, // 加载顺序,从下到上,从右到左 use: [ miniCssExtractPlugin.loader, // css-loader:将css文件变成commonjs模块加载到js中,里面内容是样式字符串 ‘css-loader’, ] }, { test: /.less$/, use: [ miniCssExtractPlugin.loader, ‘css-loader’, // less-loader:将less文件编译成css文件,需要下载less-loader和less ‘less-loader’ ] } ] }, plugins: [ // 启用插件 new miniCssExtractPlugin({ // 打包后输出的地址 filename:’css/other.css’ }) ] }
<a name="xVqIw"></a>
## 4.2css兼容性处理
安装 `npm install --D postcss-loader postcss-preset-env`
```javascript
const { resolve } = require('path')
const miniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
mode: "development",
// mode: "production",
entry: "./src/index",
output: {
filename: 'built.js',
path: resolve(__dirname, "build")
},
module: {
rules: [
{
test: /\.css$/,
use: [
miniCssExtractPlugin.loader,
'css-loader',
//---------------------------------------
//配置文件,官网文档有
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
browsers: 'last 2 versions'
},
],
],
},
},
},
//---------------------------------------
]
},
]
},
plugins: [
new miniCssExtractPlugin({
filename: 'css/other.css'
})
]
}
4.3压缩css
安装 npm i -D css-minimizer-webpack-plugin
const { resolve } = require('path')
const miniCssExtractPlugin = require('mini-css-extract-plugin')
const cssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
mode: "development",
// mode: "production",
entry: "./src/index",
output: {
filename: 'built.js',
path: resolve(__dirname, "build")
},
module: {
rules: [
{
test: /\.css$/,
use: [
miniCssExtractPlugin.loader,
'css-loader',
]
},
]
},
plugins: [
new miniCssExtractPlugin({
filename: 'css/other.css'
}),
// 不需其他配置,直接使用
new cssMinimizerWebpackPlugin()
]
}
4.4js语法检查
- 安装
npm i eslint-webpack-plugin eslint eslint-config-airbnb-base eslint-plugin-import -D - 只检查自己的js代码,第三方库是不用检查的
- 设置检查规则:package.json中设置
```javascript const { resolve } = require(‘path’) const htmlWebpackPlugin = require(‘html-webpack-plugin’) //引入插件 const ESLintPlugin = require(‘eslint-webpack-plugin’);{ ... "eslintConfig": { "extends": "airbnb-base" } ... }
module.exports = { mode: ‘development’, module: { rules: [ { test: /.css$/, use: [ “style-loader”, “css-loader” ] } ] }, plugins: [ new htmlWebpackPlugin({ template: “./src/index.html” }), // 使用插件 new ESLintPlugin({ // 设置options // 排除第三方包的检查 exclude: ‘node_modules’, // 自动修复eslint的错误 fix:true }) ] }
<a name="RiKoU"></a>
## 4.5js兼容性处理
安装 `npm install -D babel-loader @babel/core @babel/preset-env `
1. 基本js兼容性处理 --> @babel/preset-env
1. 问题:只能转换基本语法,如promise等高级语法不能转换
1. 配置
```javascript
const { resolve } = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader",
"css-loader"
]
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设:指示babel做怎么样的兼容性处理
presets: [
'@babel/preset-env',
]
}
}
]
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
})
]
}
- 全部的兼容性处理 —> @babel/polyfill(不考虑)
- 在入口index.js文件中引入就可以
import '@babel/polyfill' - 问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了
- 在入口index.js文件中引入就可以
- 需要做兼容性处理的就按需加载 —> core-js (推荐用) ```javascript const { resolve } = require(‘path’) const htmlWebpackPlugin = require(‘html-webpack-plugin’)
module.exports = { mode: ‘development’, module: { rules: [ { test: /.css$/, use: [ “style-loader”, “css-loader” ] }, { test: /.js$/, exclude: /node_modules/, loader: ‘babel-loader’, options: { // 预设:指示babel做怎么样的兼容性处理 //————————————————- presets: [ [ ‘@babel/preset-env’, { // 使用corejs的方式:按需加载 useBuiltIns: ‘usage’, // 指定core-js的版本 corejs: { version: 3 }, // 要兼容的目标浏览器 targets: { chrome: ‘60’, firefox: ‘60’, ie: ‘9’, safari: ‘10’, edge: ‘17’ } } ] ] //————————————————— } } ] }, plugins: [ new htmlWebpackPlugin({ template: “./src/index.html” }) ] }
<a name="Pz0At"></a>
## 4.6压缩js和html
在生产环境(production)下会自动压缩js和html
<a name="6Bkap"></a>
## 4.7生产环境的基本配置
安装 `npm i -D mini-css-extract-plugin postcss-loader postcss-preset-env css-minimizer-webpack-plugin eslint-webpack-plugin eslint eslint-config-airbnb-base eslint-plugin-import babel-loader @babel/core @babel/preset-env`
```javascript
const { resolve } = require('path')
// 引入插件处理html资源
const htmlWebpackPlugin = require('html-webpack-plugin')
// 引入插件将css单独打包为一个文件
const miniCssExtractPlugin = require('mini-css-extract-plugin')
// 引入插件将css压缩
const cssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
// 引入插件进行js语法检查
const ESLintPlugin = require('eslint-webpack-plugin');
//定义变量进行代码复用
const commonCssLoader = [
// 单独打包成一个文件有问题
// miniCssExtractPlugin.loader,
"style-loader",
"css-loader",
{
// 还需要在package.json中定义browserslist
// "browserslist": {
// "development": [
// "last 1 chrome version",
// "last 1 firefox version",
// "last 1 safari version"
// ],
// "production": [
// ">0.2%",
// "not dead",
// "not op_mini all"
// ]
// }
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
},
},
},
]
module.exports = {
entry: './src/js/index.js',
output: {
filename: "js/built.js",
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/i,
use: [...commonCssLoader]
},
{
test: /\.less$/i,
use: [...commonCssLoader, "less-loader"]
},
{
// js的兼容性处理
test: /\.js$/i,
exclude: /node_modules/i,
loader: 'babel-loader',
options: {
// 预设:指示babel做怎么样的兼容性处理
//---------------------------------
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js的版本
corejs: {
version: 3
},
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
//----------------------------------
}
},
{
test: /\.(jpe?g|png|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
// 指定资源打包后输出的位置和名字
generator: {
filename: 'imgs/[name].[hash:5][ext]'
},
},
{
test: /\.html$/i,
loader: 'html-loader'
},
// {webpack4中打包其他文件的方式,会出现url的问题
// exclude:/\.(html|js|css|less|jpg|png|gif)$/i,
// loader:'file-loader',
// options:{
// name:'[name].[hash:5].[ext]',
// outputPath:'media',
// },
// type: 'javascript/auto'
// },
{
// 根据实际文件添加
test: /\.(txt|woff|ttf|woff2)$/i,
type: 'asset/resource',
generator: {
filename: "media/[name].[hash:5][ext]"
}
}
]
},
plugins: [
new htmlWebpackPlugin({
template: './src/index.html'
}),
// 单独打包成一个文件有问题
// new miniCssExtractPlugin({
// //指定css打包后的文件
// filename: 'css/built.css'
// }),
new cssMinimizerWebpackPlugin(),
new ESLintPlugin({
// 设置options,同时还需在package.json文件中配置使用airbnb规则来进行检查
// "eslintConfig": {
// "extends": "airbnb-base"
// }
// 排除第三方包的检查
exclude: 'node_modules',
// 自动修复eslint的错误
fix: true
})
],
mode: 'production'
}
