avatar

目录
webpack 简单配置

单页应用

单页,只有一个 index.html

src 文件下 index.js 引入了 a.js 模块,另外还有一个 b.js,将 index.js 和 a.js 作为入口打包成一个文件 build.js 引入页面内

javascript
// webpack.config.js
let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin')
let {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports = {
entry: ['./src/index.js', './src/b.js'],
output: {
filename: 'build.[hash:8].js',
path: path.resolve('./dist')
},
mode: "development",
devServer: {
contentBase: './dist',
port: 3000,
compress: true,
open: true,
hot: true,
},
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html',
hash: true, // 引 js 的时候通过查询参数带 hash,用来清理缓存
}),
new CleanWebpackPlugin(),
]
}

entry 数组形式,两个入口

插件:

html-webpack-plugin:根据源文件中 html template 打包出一个 html ,自动引入打包的 js 文件

clean-webpack-plugin:output 的 filename 添加 [hash] 后,每次更新内容会产生新 hash 后缀,此插件会删除之前的打包文件,只保留有最新 hash 后缀的文件

多页应用

多页,设置两个 html ,index.html 使用 index.js ,main.html 使用 main.js

javascript
// webpack.config.js
let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin')
let {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports = {
entry: {
index_: './src/index/index.js',
main_: './src/main/main.js'
},
output: {
filename: '[name].[hash:8].js', //多页应用使用 [name]
path: path.resolve('./dist')
},
mode: "development",
devServer: {
contentBase: './dist',
port: 3000,
compress: true,
open: true,
hot: true,

},
plugins:[
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index/index.html',
hash: true, // 引 js 的时候通过查询参数带 hash,用来清理缓存
chunks: ['index_'] // 表示引入的 js 模块
}),
new HtmlWebpackPlugin({
filename: 'main.html',
template: './src/main/main.html',
hash: true, // 引 js 的时候通过查询参数带 hash,用来清理缓存
chunks: ['main_']
}),
new CleanWebpackPlugin(),
]
}

entry 使用对象形式 ,key 为 chunk name,value 为入口文件

output 多页需要输出多个打包 js 文件,filename 设置 [name],引用 entry 设置的 chunk name,打包出两个 js 文件分别为 index_.6798b082.jsmain_.6798b082.js(加 hash 后缀)

因为多页有两个 html,所以 plugins 数组中需要两个 HtmlWebpackPlugin 实例,chunks 值为数组,表示 html 引入的 chunk name

热更新(以单页为例)

热更新:不刷新页面,只更新修改的部分

为什么要使用热更新:性能优化,文件太多都刷新会浪费性能;vuex,redux状态管理刷新会丢失

单页,单入口

javascript
// webpack.config.js
let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin')
let {CleanWebpackPlugin} = require('clean-webpack-plugin')
let Webpack = require('webpack')

module.exports = {
entry: './src/index.js',
output: {
filename: 'build.[hash:8].js',
path: path.resolve('./dist')
},
mode: "development",
devServer: {
contentBase: './dist',
port: 3000,
compress: true,
open: true,
hot: true, // 开启热更新,需要引入 webpack 自带的热更新插件 HotModuleReplacementPlugin
},
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html',
hash: true, // 引 js 的时候通过查询参数带 hash,用来清理缓存
}),
new CleanWebpackPlugin(),
new Webpack.HotModuleReplacementPlugin(),
]
}

引入 webpack 自带热更新插件 HotModuleReplacementPlugin,devServer 设置 hot 为 true 开启热更新

对入口文件 index.js 监控热更新

javascript
// index.js
if(module.hot){
module.hot.accept()
}

加载样式

webpack 默认只能处理 js 模块,处理其他文件例如 css 、less需要 loader 加载

  • style-loader:将样式文件变成 style 标签插入页面,
  • css-loader:把 css 变成 js 模块,默认支持热更新功能
  • less-loader :加载 less

要处理和引入样式文件,一定是因为入口文件引入了相关样式模块,例如入口文件 index.js 引入了 css 模块和 less 模块

javascript
// index.js
import './index.css'
import './style.less'

<style>标签引入样式

将 css 文件和 less 文件处理,变成<style>标签插入<body>,打包后只有 build.js 文件,样式也被处理进去,因为有 css-loader ,支持热更新

javascript
// webpack.config.js
module.exports = {
module:{
rules:[
{
test: /\.css$/,
use:[
{loader: 'style-loader'},
{loader: 'css-loader'}
]
},
{
test: /\.less$/,
use:[
{loader: 'style-loader'},
{loader: 'css-loader'},
{loader: 'less-loader'}
]
},
]
}
}

如果只用 style-loader 加载样式,样式都会在打包的 js 文件中,文件会很大

可以使用 mini-css-extract-plugin 抽离样式到一个 css 文件,通过 link 引入

使用 postcss-loader 和 autoprofixer 插件给样式加浏览器兼容前缀

使用 copy-webpack-plugin :用来拷贝文件

javascript
// webpack.config.js
let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin')
let { CleanWebpackPlugin } = require('clean-webpack-plugin')
let Webpack = require('webpack')
let MiniCssExtractPlugin = require('mini-css-extract-plugin')
let CopyWebpackPlugin = require('copy-webpack-plugin')


module.exports = {
entry: './src/index.js',
output: {
filename: 'build.[hash:8].js',
path: path.resolve('./dist')
},
mode: "development",
devServer: {
contentBase: './dist',
port: 3000,
compress: true,
open: true,
hot: true, // 开启热更新,需要引入 webpack 自带的热更新插件 HotModuleReplacementPlugin
},
plugins: [
new CopyWebpackPlugin([
{
from: './src/doc',
to: 'public'
}
]),
new MiniCssExtractPlugin({
filename: './css/style.css',
}),
new HtmlWebpackPlugin({
template: './src/index.html',
hash: true, // 引 js 的时候通过查询参数带 hash,用来清理缓存
}),
new CleanWebpackPlugin(),
new Webpack.HotModuleReplacementPlugin(),
],
module: {
rules: [
{
test: /\.css$/, // 正则,为了匹配文件使用
use: [
{ loader: MiniCssExtractPlugin.loader },
{ loader: 'css-loader' },
{ loader: 'postcss-loader' }
],
},
{
test: /\.less$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{ loader: 'css-loader' },
{ loader: 'postcss-loader' },
{ loader: 'less-loader' },
],
}
]
}
}

要给样式添加前缀还需要设置 postcss 的配置文件

javascript
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
文章作者: GRIT
文章链接: https://grit0821.github.io/Blog/2020/01/21/webpack-%E7%AE%80%E5%8D%95%E9%85%8D%E7%BD%AE/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Grit's World