我的webpack学习之路(webpack初步认知和webpack基础打包)
我的webpack学习之路(关于webpack的性能优化)
关于我的学习笔记
项目目录
---开发环境基本配置
---src
---css
---iconfont.css //阿里矢量图标库下载的素材
---index.less
---img
---1.jpg
---js
---index.js
---other // 阿里矢量图标库下载的素材
--- iconfont.eot
--- iconfont.svg
--- iconfont.ttf
--- iconfont.woff
---webpack.config.js
webpack.config.js配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js', // 在build下创建js文件夹,输出build.js
path: resolve('build')
},
module: {
rules: [
// 处理less样式文件
{
test: /\.less$/,
use: [ 'style-loader','css-loader', 'less-loader']
},
{
test: /\.css$/,
use: [ MiniCssExtractPlugin.loader ,'css-loader']
},
// 处理css图片资源
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
outputPath: 'img' // 在build下创建img文件夹,放入处理过后的图片
}
},
// 处理html图片资源
{
test: /\.html$/,
loader: 'html-loader'
},
// 处理其他资源
{
exclude:/\.(html|css|js|less|jpg|png|gif)$/,
loader: 'file-loader',
options:{
outputPath: 'other'// 在build下创建other文件夹,放入处理过后的其他资源(我这里主要是字体资源)
}
}
]
},
plugins: [
//处理html模板
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/build.css' // 在build下创建css文件夹,放入处理过后的其他资源
})
],
mode: 'development'
}
能帮助我们开发时有修改代码,不用一次又一次重新打包编译,会帮助我们自动编译
这里需要webpack-dev-server,需要下载
npm i webpack-dev-server -D
// webpack.condig.js
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新)
// 特点只会在内存中编译打包,不会有任何输
// 启动devServer指令为npx webpack-dev-server
devServer: {
// 代表运行的项目目录
contentBase: resolve(__dirname, 'build'),
// 启动gizp压缩
compress:true,
// 端口号
prot: 9000
}
使用mini-css-extract-plugin插件
在处理css文件时,用到了两个loaderstyle-loader和css-loader
css-loader是处理css文件写到js文件中。再由style-loader在html中创建style标签写入样式。
而mini-css-extract-plugin是从js文件中提取css样式,单独处理到css文件中,所以不需要再使用style-loader。mini-css-extract-plugin里内置了处理css文件的loader,替换掉style-loader即可
const MiniCssExtractPlugin = reuqire('mini-css-extract-plugin')
// 替换style-loader
// 'style-loader' => MiniCssExtractPlugin.loader
// 在plugins中添加插件
new MiniCssExtractPlugin()
// 对输出的css文件的位置和名字处理
new MiniCssExtractPlugin({
// 输出到对应出口文件下,创建css文件夹放入输出的名为build.css问文件
filename: 'css/build.css'
})
打包处理后的html文件会自动映入css下的build.css
webpack对css进行兼容处理如要用到一个库:postcss => postcss-loader post-preset-env
这里需要npm下载这两个包,然后就可以在webpack.config.js中处理
npm i postcss-loader post-preset-env -D
// webpack。config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
function resolve(dir) {
return path.join(__dirname, dir)
}
// 设置node环境变量,修改默认,使兼容处理以开发模式为准
process.env.NODE_ENV = 'development'
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve('build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
// css兼容处理需要使用一个库:postcss => postcss-loader postcss-preset-env
// postcss-preset-env这个插件能帮助我们识别某些环境,从而加载某些配置,能让我们的兼容性精确的浏览器的某一个版本
// 帮助postcss找到package.json中browserlist里面的配置,透过配置加载制定的css兼容性样式
/**
* "browserslist": {
* 开发环境 --> 设置node环境变量: process.env.NODE_ENV = development
"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'
// 修改loader配置
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [['postcss-preset-env', {
}]]
}
}
}
]
}
]
},
plugins: [
//处理html模板
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/build.css'
})
],
mode: 'development'
}
webpack.config.js配置好了还需要配置browsetslist: {}
关于browsetslist的具体配置可以到GitHub上搜索
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
关于post-preset-env配置browserslist,版本不同也有不同的配置,可以自行搜索其他配置方法
压缩css只需要用到一个插件:optimize-css-assets-webpack-plugin
只需要在webpack.config.js中使用这个插件就可以
// 先引用
const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
//使用
plugins: [
... // 其他插件
new optimizeCssAssetsWebpackPlugin()
]
如上配置完成后就可以运行webpack处理,压缩css文件了
首先进行js语法检查是借助loader,所以需要想在相应依赖。eslint-loader,这个loader又依赖eslint这个库。
注意:eslint只检查自己写的代码,第三方库是不检查的
设置规则:
在package.json添加eslintConfig配置
"eslintConfig": {
"extends": "airbnb-base"
}
推荐使用airbnb规则,airbnb对应需要的依赖: eslint-config-airbnb-base、eslint、eslint-plugin-import
airbnb规则可以在GitHub上查看详细规则,对应使用的依赖是使用方法可以在npmjs.com中搜索eslint
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require('path');
function resolve(dir) {
return path.join(__dirname,dir)
}
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve('build')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules内的第三方库,不检查,会报错
loader: 'eslint-loader',
options: {
// 自动修复eslint错误
fix: true
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
}
设置了fix:true会在源代码中自动修复格式错误
在使用airbnb规则,在js中使用console.log()时会爆出警告,但不会影响运行,这里需要借助eslint-disable-next-line来告诉eslint这下一行eslint规则失效,eslint-disable-next-line是以注释的方式使用
// 下一行eslint所有规则都失效
// eslint-disable-next-line
console.log('hello eslint'); // 这一行eslint的规则就不会生效
首先js兼容性处理需要用到三个依赖:babel-loader、@babel/preset-env、@babel/core
npm i babel-loader @babel/preset-env @babel/core -D
js兼容处理总的来说有三种方法:
1、基本的js兼容处理:—> @babel/preset-env;
// index.js
const add = (x,y) => {
return x + y
}
console.log(add(1,2))
const promise = new Promise((resolve) => {
setTimeout(() => {
console.log('aaaaaaaaaaaa')
resolve()
}, 1000)
})
console.log(promise)
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设:指示babel做怎样的兼容性处理
presets: ['@babel/preset-env'] // 这里做了一个基本的预设环境的兼容性处理
}
}
]
}
如上在loader中配置babel就做好了一个简单兼容性处理,运行webpack命令后,查看输出的js文件
会看到const被转为var,箭头函数被转为function等兼容性写法
问题:这种方法只能转换基本语法,如promise等高级语法是不能转换的,如上图,promise没有被转换,指示还是只转换了const和箭头函数
2、全部js兼容性处理 ---->@babel/polyfill
全部兼容性处理需要用到@babel/polyfill这个依赖
npm i @babel/polyfill -D
使用方法:
不需要在webpack.config.js中引用,而是在js文件中引用,如下
// index.js
import '@babel/polyfill'
const add = (x,y) => {
return x + y
}
console.log(add(1,2))
const promise = new Promise((resolve) => {
setTimeout(() => {
console.log('aaaaaaaaaaaa')
resolve()
}, 1000)
})
console.log(promise)
import引用后即可,运行webpack打包后,打开build.js(打包后的js文件)。就会发现build.js文件体积变大,其中多了很多兼容处理。这是因为@babel/polyfill,将所有兼容性处理全部引入进来了,比较暴力的处理方法
问题:我们只需要解决我们需要的兼容处理,如果将所有兼容代码全部引入,文件体积变大
3.js兼容处理按需加载 ---->core-js
npm i core-js -D
注意:这种方法不能和第二种方法同时使用,需要注释掉@babel/polyfill的引用
配置如下
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs:{
version: 3
},
// 指定兼容性做到那个版本的浏览器
targets:{
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}
]
},
注意:presets的配置,和第一种方法有些不一样:presets:[ [ …这里写loader配置 ] ],两个数组
然后运行webpack命令就可以做到兼容性按需加载了~
这两部分的压缩很简单
首先js代码压缩:生产环境下(mode:‘droduction’),会自动压缩js代码
mode: 'droduction'
在我的webpack学习之路(webpack初步认知和webpack基础打包)介绍的webpack的五个核心概念中的mode中知道在生产环境下,会加载很多插件,其中有一个插件为UglifyJsPlugin会自动压缩js代码,无需关注其他
然后是压缩html代码:这里我们只需要在HtmlWebpackPlugin插件中添加一个新的配置minify即可
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
// 压缩html代码
minify: {
collapseWhitespace: true, // 移除空格
removeComments: true, // 移除注释
}
})
],
如上配置就可以实现html代码压缩
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 单独提取css文件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') // 压缩css
const HtmlWebpackPlugin = require('html-webpack-plugin')
function resolve(dir) {
return path.join(__dirname,dir)
}
/*
css兼容性处理
需要在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"
]
},
postcss-loader默认使用生产环境
通过process.env.NODE_ENV来改变postcss-loade的处理环境
*/
process.env.NODE_ENV = 'production' // node环境变量,决定使用browerlist的那个环境
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
// 样式兼容
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [['postcss-preset-env', {
}]]
}
}
}
]
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/build.js',
path: resolve('build')
},
module: {
rules:[
/*
正常来讲,一个文件只能被一个loader处理。
当一个文件要被对个loader处理,那么一定要指定laoder的执行顺序
先执行eslint 在执行babel
因为:1.当代码格式出错时会报错,在网下执行没有意义。2.如果先执行babel,会将转化为es5,eslint也会对es5语法报错
*/
// 处理js检查...
// 在package.json添加eslintConfig配置 --->airbnb(为了更加友好和专业使用airbnb规则)
// "eslintConfig": {
// "extends": "airbnb-base"
// }
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules,
loader: 'eslint-loader',
// 设置优先执行
enforce: 'pre',
options: {
fix: true
}
},
// js兼容处理..
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
corejs: {
version: 3},
targets: {
chrome: '60'
}
}
]
]
}
},
// css处理 ....
{
test: /\.css$/,
use: [...commonCssLoader]
},
// less处理 ....
{
test: /\.less$/,
use: [
...commonCssLoader,
'less-loader'
]
},
// 图片处理 ...
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
outputPath: 'img'
}
},
// html图片处理
{
test: /\.html$/,
loader: 'html-loader'
},
// 其他文件处理
{
exclude: /\.(html|css|js|less|jpg|png|gif|less)$/,
loader: 'url-loader',
options: {
outputPath: 'other'
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/build.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
// 处理html结构
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
removeComments: true,
collapseWhitespace: true
}
})
],
mode: 'production'
}
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"babel-loader": "^8.1.0",
"core-js": "^3.6.5",
"css-loader": "^5.0.0",
"eslint": "^7.12.1",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.1",
"file-loader": "^6.2.0",
"html-loader": "^1.3.2",
"html-webpack-plugin": "^4.5.0",
"less": "^3.12.2",
"less-loader": "^7.0.2",
"mini-css-extract-plugin": "^1.2.1",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^4.0.4",
"postcss-preset-env": "^6.7.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"workbox-webpack-plugin": "^5.1.4"
},