CSS
提取 css 成单独文件
- npm install —save-dev mini-css-extract-plugin (需要配置module和plugins)
- 本插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文 件,并且支持 CSS 和 SourceMaps 的按需加载。 本插件基于 webpack v5 的新特性构建,并且需要 webpack 5 才能正常工作。
const MiniCssExtractPlugin = require("mini-css-extract-plugin")module: {rules: [{test: /\.css$/i,//用MiniCssExtractPlugin.loader替代style-loaderuse: [MiniCssExtractPlugin.loader, 'css-loader'],},]},plugins: [//提取css为单独文件new MiniCssExtractPlugin({// 对输出的css文件进行重命名filename: 'css/built.css',})],
兼容性处理 PostCSS
方式一 新postcss是一个用 JavaScript 工具和插件转换 CSS 代码的工具。比如可以使用Autoprefixer插件自动获取浏览器的流行度和能够支持的属性,并根据这些数据帮 我们自动的 为 CSS 规则添加前缀,将最新的 CSS 语法转换成大多数浏览器都能理解的语法。npm install --save-dev postcss-loader autoprefixer配置package.json
rules: [{test: /\.css$/,exclude: /node_modules/,use: [loader: 'style-loader',loader: 'css-loader',loader: 'postcss-loader']}]
然后在项目根目录下创建 postcss.config.js : 引入autoprefixer插件
module.exports = {plugins: [require('autoprefixer')]}
package.json
"browserslist": ["> 1%", //全球浏览器使用率大于1%或大于等于1%"last 2 versions" //每个浏览器中最新的两个版本]
方式二 旧
- npm install —save-dev postcss-loader@3 postcss-preset-env@5 新版本把配置中箭头函数改为数组
- 参考下方“旧代码汇总”
拓展:CSS模块
CSS模块: 多人编写的样式可能会冲突,开启 CSS 模块可以解决这个问题。 vue react脚手架也是这个方法
webpack.config.js
rules: [{test: /\.css$/,use: ['style-loader',{loader: 'css-loader',options: {// 开启css模块modules: true}},'postcss-loader']}]
postcss-nested 提供 编写嵌套的样式语法。
postcss.config.js : 在以上代码中继续拓展
module.exports = {plugins: [require('autoprefixer'),//提供自动给样式加前缀去兼容浏览器require('postcss-nested')//提供编写嵌套的样式语法]}
css 编写嵌套css代码
body {display: flex;flex-direction: column;.box {width: 100px;height: 100px;background: red;}}
js引入
/ 开启 css 模块后,可以导入模块import style from './style.css'const div = document.createElement('div')div.textContent = 'hello webpack'// style 里可以识别 class 样式div.classList.add(style.box)document.body.appendChild(div)
效果

可以部分开启 CSS 模块模式,比如全局样式可以冠以 .global 前缀,如:
- *.global.css 普通模式
- .css css module模式
这里统一用 global 关键词进行识别。用正则表达式匹配文件:``json // css module { test: new RegExp(^(?!.\.global).*\.css`), use: [ {
}, { loader: ‘css-loader’, options: {loader: 'style-loader'
} }, {modules: true,localIdentName: '[hash:base64:6]'
} ], exclude:[path.resolve(__dirname, ‘..’, ‘node_modules’)] }loader: 'postcss-loader'
// 普通模式
{
test: new RegExp(^(.*\\.global).*\\.css),
use: [
{
loader: ‘style-loader’
},
{
loader: ‘css-loader’,
},
{
loader: ‘postcss-loader’
}
],
exclude:[path.resolve(__dirname, ‘..’, ‘node_modules’)]
}
<a name="QQzwV"></a>### 压缩- 将mode为生产环境- webpack5以下 - npm install --save-dev optimize-css-assets-webpack-plugin- webpack5以上 - npm install --save-dev css-minimizer-webpack-plugin```javascriptconst CssMinimizerPlugin = require('css-minimizer-webpack-plugin')module.exports = {// 生产模式mode: 'production',// 优化配置optimization: {minimizer: [new CssMinimizerPlugin(),],},}
JS
兼容性处理
babel
babel 7 以上的版本
- webpack只能处理基本语法,像promise是不能处理的
- npm install —save-dev babel-loader @babel/core @babel/preset-env
babel-loader: 在webpack里应用 babel 解析ES6的桥梁@babel/core: babel核心模块@babel/preset-env: babel预设,一组 babel 插件的集合
- regeneratorRuntime 插件 : 是webpack打包生成的全局辅助函数,由babel生成,用于兼 容async/await的语法
```
这个包中包含了regeneratorRuntime,运行时需要
npm install —save @babel/runtime
- npm install —save-dev babel-loader @babel/core @babel/preset-env
这个插件会在需要regeneratorRuntime的地方自动require导包,编译时需要
npm install —save-dev @babel/plugin-transform-runtime
- `@babel/runtime` : 这个包中包含了regeneratorRuntime,运行时需要
- `@babel/plugin-transform-runtime` : 在需要regeneratorRuntime的地方自动require导包,编译时需要
```javascript
module:{
rules:[
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
[
'@babel/plugin-transform-runtime'
]
]
}
}
}
]
},
babel 7 以下的版本使用core-js
- 全部处理core-js(3版本) - npm install —save-dev core-js
npm install --save @babel/polyfill
import '@babel/polyfill'
console.log(Array.from([1, 2, 3], x => x + x))
此时打包后会引入Array.from的兼容代码。但不提倡这样导入, 这样做的缺点是会全局引入整个 polyfill包,比如 Array.from 会全局引入,不但包的体积大,而且还会污染全局环境。
进一步优化 Polyfillsbabel-preset-env package 通过 browserslist 来转译那些你浏览器中不支持的特性。这个 preset 使用 useBuiltIns选项,默认值是 false ,这种方式可以将全局 babel-polyfill 导入,改进为更细粒度的 import 格式: npm i babel-loader @babel/core @babel/preset-env -D
由于@babel/polyfill在7.4.0中被弃用,我们建议直接添加corejs并通过corejs选项设 置版本。(测试不需要配置core)npm i core-js@3 -S
webpack.config.json
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 指定兼容性做到哪个版本浏览器
targets: [
"last 1 version",
"> 1%",
],
useBuiltIns: 'usage',// 按需加载
corejs: 3,// 添加corejs配置 版本3
}
]
]
}
}
}
]
useBuiltIns: 参数有 “entry”、”usage”、false 三个值 默认值是 false ,此参数决定了babel打包时如何处理@babel/polyfilll 语句。 “entry”: 会将文件中 import @babel/polyfilll 语句 结合 targets ,转换为一系 列引入语句,去掉目标浏览器已支持的 polyfilll 模块,不管代码里有没有用到,只要 目标浏览器不支持都会引入对应的 polyfilll 模块。 “usage”: 不需要手动在代码里写 import @babel/polyfilll ,打包时会自动根据 实际代码的使用情况,结合 targets 引入代码里实际用到部分 polyfilll 模块 “false”: 对 import‘@babel/polyfilll’不作任何处理,也不会自动引入 polyfilll 模块。 需要注意的是在 webpack 打包文件配置的 entry 中引入的 @babel/polyfill 不会根据 useBuiltIns 配置任何转换处理。
压缩
webpack4.26以上版本压缩JS使用terser(terser-webpack-plugin),因为uglify(uglify-js)这个库不维护了
- webpack.config.js配置
mode: 'production'改为开发模式则会自动压缩 - 但是 如果设置了压缩css的MiniCssExtractPlugin则需要使用插件
terser-webpack-plugin才能压缩js npm i terser-webpack-plugin -D```javascript const CssMinimizerPlugin = require(‘css-minimizer-webpack-plugin’); const TerserPlugin = require(‘terser-webpack-plugin’)
module.exports = { // 生产模式 mode: ‘production’, // 优化配置 optimization: { minimizer: [ //压缩css new CssMinimizerPlugin(), //压缩js new TerserPlugin() ], }, }
<a name="ZyvzZ"></a>
### 代码分离
-> 生产环境性能优化&规范 ->code split(代码分割)
<a name="m2P4D"></a>
### 懒加载
-> 生产环境性能优化&规范 ->lazy loading(JS文件懒加载/预加载)
<a name="yeMnS"></a>
## TypeScript
<a name="Z9fCy"></a>
### 安装配置使用
安装我们的ts和对应的loader : `npm install --save-dev typescript ts-loader ` <br /> 配置文件 - tsconfig.json : `npx tsc --init` (自动生成)<br /> 里面注释掉了绝大多数配置 根据需要配置
> tsconfig.json
```json
{
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"sourceMap": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"allowJs": true,
"moduleResolution": "node"
}
}
package.json
const path = require('path');
module.exports = {
entry: './src/index.ts',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.(ts|tsx)$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
使用第三方类库
在从 npm 上安装第三方库时,一定要记得同时安装这个库的类型声明文件(typing definition)这样ts才有提示。
我们可以从 TypeSearch中找到并安装这些第三方库的类型声明文件(https://www.ty pescriptlang.org/dt/search?search=) 。
举个例子,如果想安装 lodash 类型声明文件,我们可以运行下面的命令: npm install --save-dev @types/lodash
eslint & ts
注意,如果要使用eslint,使用初始化命令的时候,记得选择“使用了typesctipt”。
HTML
html 压缩
mode: ‘production’ 改为开发模式则会自动压缩
- 新版本webpack如5.39.1不需要配置
- 老版本如webpack如54.41.6则需配置minify ```json const HtmlWebpackPlugin = require(‘html-webpack-plugin’);//创建空html
module.exports = { // plugins的配置 plugins: [ new HtmlWebpackPlugin({ … // 压缩html代码 minify: { // 移除空格 collapseWhitespace: true, // 移除注释 removeComments: true, }, }), ], mode: ‘production’, }
---
<a name="mziCs"></a>
## 旧代码汇总
**webpack.config.js**
```javascript
// resolve用来拼接绝对路径的方法
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');//创建空html
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //从js中提取css为单独文件
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');//压缩CSS
const ESLintPlugin = require('eslint-webpack-plugin');//js语法检查
// 设置 nodejs 环境变量与mode没关系: 好决定使用browserslist的哪个环境
// 默认是开发环境 , 这里是为了测试css兼容性
process.env.NODE_ENV = 'development';
// 复用loader的写法
const commonCssLoader = [
// 这个loader取代style-loader。作用:提取js中的css成单独文件然后通过link加载
{
loader: MiniCssExtractPlugin.loader,
options: {
//解决图片路径问题
publicPath: '../'
}
},
// css-loader:将css文件整合到js文件中
// 经过css-loader处理后,样式文件是在js文件中的
// 问题:1.js文件体积会很大2.需要先加载js再动态创建style标签,样式渲染速度就慢,会出现闪屏现象
// 解决:用MiniCssExtractPlugin.loader替代style-loader
'css-loader',
{
/*
css兼容性处理
修改loder的默认配置使用对象写法 如下
postcss需要通过package.json中browserslist里面的配置加载指定的css兼容性样式
在package.json中定义browserslist:
*/
loader: 'postcss-loader',
options: {
ident: 'postcss', // 基本写法
plugins: () => [
// postcss的插件
require('postcss-preset-env')(),
],
},
},
]
module.exports = {
// webpack配置
// 入口起点
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
// loader的配置
module: {
rules: [
{
test: /\.css$/,
// 使用哪些loader进行处理
use: [...commonCssLoader]
},
{
test: /\.s[ac]ss$/i,
//'...'展开
// 顺序: scss->css->添加兼容->把css加载到js中->提取为单独文件
use: [...commonCssLoader,'sass-loader']
},
/*
正常来讲,一个文件只能被一个loader处理
当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序
先执行eslint再执行babel(用enforce)
*/
{
/*eslint-loader: js语法检查是以前的已被弃用(可不看以下注释)
现使用eslint-webpack-plugin 只需要配置plugins
设置检查规则:使用airbnb规则指南
package.json 中 eslintConfig 中设置~
"eslintConfig": {
"extends": "airbnb-base"
}
airbnb 需要下载下方几个库
airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint
*/
/* eslint-loader配置
{
test: /\.js$/,
//只检查自己写的源代码,第三方的库是不用检查的
exclude: /node_modules/,
//优先执行
enforce: 'pre',
loader: 'eslint-loader',
options: {
// 打包时自动修复 eslint 的错误
fix: true
}
}*/
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设:指示 babel 做怎么样的兼容性处理
//新版本需要添加targets
presets: [
['@babel/preset-env',
//使用core-js时不配置
// { targets: "defaults" },
{
// 按需加载
useBuiltIns: 'usage',
// 指定 core-js 版本
corejs: {
version: 3
},
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
],
//babel 7 以上的版本 利用 @babel/plugin-transform-runtime 插件还能以沙箱垫片的方式防止污染全局, 并抽离公共的 helper function , 以节省代码的冗余
plugins: ['@babel/plugin-transform-runtime']
}
},
{
// url-loader:处理图片资源,问题:默认处理不了html中的img图片
test: /\.(jpg|png|gif)$/,
// 需要下载 url-loader file-loader
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理,优点:减少请求数量(减轻服务器压力),缺点:图片体积会更大(文件请求速度更慢)
// base64在客户端本地解码所以会减少服务器压力,如果图片过大还采用base64编码会导致cpu调用率上升,网页加载时变卡
limit: 8 * 1024,
// 给图片重命名,[hash:10]:取图片的hash的前10位,[ext]:取文件原来扩展名
name: '[name].[hash:10].[ext]',
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是conmonjs,解析时会出问题:[object Module]
// 解决:关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
//指定打包路径
outputPath: 'imgs',
},
},
{
test: /\.html$/,
//@0.5.5 否则图片打不开
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: 'html-loader',
},
{
// 排除html|js|css|less|jpg|png|gif文件
exclude: /\.(html|js|css|scss|jpg|png|gif)/,
// file-loader:处理其他文件
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media',
},
}
]
},
// plugins的配置
plugins: [
//提取css为单独文件
new MiniCssExtractPlugin({
// 对输出的css文件进行重命名
filename: 'css/built.css',
}),
// 压缩csswebpack5以下
//new OptimiziCssAssetsWebpackPlugin(),
// 压缩csswebpack5以上
new CssMinimizerWebpackPlugin(),
// html-webpack-plugin
// 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
// 需求:需要有结构的HTML文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
template: './src/index.html',
// 压缩html代码
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true,
},
}),
new ESLintPlugin({
//语法自动矫正
fix:true
})
],
// 生产环境下会自动压缩js代码
mode: 'production',
}
package.json
{
...,
"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"
]
},
}
