webpack4学习笔记
一些核心概念文档都有,这里记录一下实例代码。
清除打包文件的插件:clean-webpack-plugin
npm install clean-webpack-plugin --save-dev
webpack.config.js
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
plugins:[
new CleanWebpackPlugin()
]
//可以查看clean-webpack-plugin插件 返回的是{CleanWebpackPlugin}
打包html文件:
npm install html-webpack-plugin --save-dev
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
template: './src/index.html'
})
打包图片文件:
npm install html-loader url-loader --save-dev
webpack.config.js
{
test:/\.(png|jpeg)$/,
use:[
{
loader:'url-loader',
options:{
// 图片大小小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 8 * 1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出问题:[object Module]
// 解决:关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]取文件原来扩展名
name: '[hash:10].[ext]'
}
}
]
},
{
test:/\.html$/,
use:'html-loader'
}
- 打包样式文件:
npm install style-loader css-loader sass-loader sass-node postcss-loader autoprefixer
{
test:/\.(scss)$/,
use:['style-loader','css-loader','sass-loader','postcss-loader']
}
postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
]
})
]
};
webpack-dev-server
的使用:
npm install webpack-dev-server --save-dev
webpack.config.js
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动devServer指令为:npx webpack-dev-server
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, "build"),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true,
},
package.json
"server":"npx webpack-dev-server"
当运行npm run server时报错: Error: Cannot find module 'webpack-cli/bin/config-yargs’
因为webpack和webpack-dev-server兼容问题,官网中使用以下方式启动:
"server":"npx webpack serve"
目前前的webpack.config.js
const {resolve} = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "js/bundle.js",
path: resolve(__dirname, "dist"),
publicPath: "./",
},
module: {
rules: [
{
test: /\.(css)$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(scss)$/,
use: ["style-loader", "css-loader", "sass-loader", "postcss-loader"],
},
{
test: /\.(jpg|png|jpeg)$/,
use: [
{
loader: "url-loader",
options: {
// 图片大小小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 8 * 1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出问题:[object Module]
// 解决:关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]取文件原来扩展名
name: "[hash:10].[ext]",
outputPath:'img'
},
},
],
},
{
test: /\.html$/,
use: "html-loader",
},
// 打包其他资源(除了html/js/css资源以外的资源)
{
// 排除css/js/html资源
exclude: /\.(css|js|html|scss|jpg|png|jpeg)$/,
loader: "file-loader",
options: {
name: "[hash:10].[ext]",
outputPath: 'media'
},
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
template: "./src/index.html",
}),
],
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动devServer指令为:npx webpack-dev-server
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, "build"),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true,
},
mode: "development",
};
生产环境下的操作
提取css文件
npm install mini-css-extract-plugin --save-dev
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
rules:[
{
test: /\.(css)$/,
use: [
// 创建 style 标签,将样式放入
// 'style-loader',
// 这个 loader 取代 style-loader。作用:提取 js 中的 css 成单独文件
MiniCssExtractPlugin.loader,
"css-loader"],
},
]
plugins:[
new MiniCssExtractPlugin({
// 对输出的 css 文件进行重命名
filename: 'css/built.css'
})
]
压缩css文件
npm install --save-dev optimize-css-assets-webpack-plugin
plugins:[
// 压缩 css
new OptimizeCssAssetsWebpackPlugin()
]
配置eslint
npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
webpack.config.js
/*语法检查: eslint-loader eslint 注意:只检查自己写的源代码,第三方的库是不用检查的 设置检查规则: package.json 中 eslintConfig 中设置~ "eslintConfig": { "extends": "airbnb-base" } airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint */
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
// 自动修复 eslint 的错误
fix: true,
},
},
package.json
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"browser": true
}
}
测试的时候使用console.log输出,如果提示 warning Unexpected console statement no-console 则eslint成功。
js兼容问题:这里只记录以下webpack4对js兼容处理问题
package.json
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/preset-env": "^7.12.7",
"babel-loader": "^8.2.2",
"core-js": "^3.8.0",
"html-webpack-plugin": "^4.5.0",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11"
},
webpack.config.json
module: {
rules: [
/*
js兼容性处理:babel-loader @babel/core
1. 基本js兼容性处理 --> @babel/preset-env
问题:只能转换基本语法,如promise高级语法不能转换
2. 全部js兼容性处理 --> @babel/polyfill
问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~
3. 需要做兼容性处理的就做:按需加载 --> core-js
*/
{
test: /\.js$/,
exclude: /node_modules/,
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'
}
}
]
]
}
}
]
},
压缩HTML
const HtmlWebpackPlugin = require("html-webpack-plugin");
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
template: "./src/index.html",
// 压缩html代码
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true
}
}),
生产环境的webpack.config.js配置
主要提取公共配置,明确loader的执行先后顺序
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';
// 复用loader
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
// 还需要在package.json中定义browserslist
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [require('postcss-preset-env')()]
}
}
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [...commonCssLoader]
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
/*
正常来讲,一个文件只能被一个loader处理。
当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
先执行eslint 在执行babel
*/
{
// 在package.json中eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
// 优先执行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: {version: 3},
targets: {
chrome: '60',
firefox: '50'
}
}
]
]
}
},
{
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
mode: 'production'
};