这是我参与「第四届青训营 」笔记创作活动的的第15天
webpack学习
前端发展受限原因:
- 依赖手工,过程繁琐
- 当代码文件之间有依赖的时候,就得严格按依赖顺序书写
- 开发与生产环境一致,难以接入 TS 或 JS 新特性
- 比较难接入 Less、Sass 等工具
- JS、图片、CSS 资源管理模型不一致
什么是webpack ——前端工程化工具
本质上是一种前端资源编译和打包的工具
主要功能
它提供了友好的前端模块化开发支持,以及代码压缩混淆,处理浏览器js的兼容性,性能优化等强大的功能
如何使用webpack
- 安装
npm i -D webpack webpack-cli - 编辑配置文件
webpack.config.js
const path = require('path')
module exports = {
//入口:可以是字符串/数组/对象,这里我们入口只有一个,所以写一个字符串即可
entry: './src/main.js',
//出口:通常是一个对象,里面至少包含两个重要属性,path和filename
output: {
path: path.resolve(__dirname, 'dist'),//注意:path通常是一个绝对路径
filename: '[name].js',//也可以写死成bundle.js
//配置发布到线上资源的 URL 前缀
//publicPath: 'dist<img src="/'," alt="" width="70%" />
},
module: {
//rules(规则)
rules: [
{
test: /\.css$/,//正则表达式
/* css-loader只负责将css文件进行加载
style-loader负责将样式添加到DOM中
使用多个loader是加载顺序是从右往左(绕脑袋,np)*/
use: ['style-loader', 'css-loader']
},
]
}
}
- 执行编译命令
npm webpack
编译流程
配置总览
webpack使用
处理CSS
- 安装Loader
npm add -D css-loader style-loader - 添加 module 处理css文件
//module配置
module: {
//rules(规则)
rules: [
{
test: /\.css$/,//正则表达式
/* css-loader只负责将css文件进行加载
style-loader负责将样式添加到DOM中
使用多个loader是加载顺序是从右往左(绕脑袋,np)*/
use: ['style-loader', 'css-loader']
},
]
[}]
问题
引入bable
问题
- 安装Loader
npm i -D @babel/core @babel/preset-env babel-loader - 添加 module 处理css文件
//module配置
module: {
//rules(规则)
rules: [
rules: [{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}]
]
[}]
问题
Babel · The compiler for next generation JavaScript
@babel/preset-typescript · Babel
生成HTML
- 安装Loader
npm i -D html-webpack-plugin - 添加 module 处理css文件
const path = require('path')
const HTMLWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index',
mode: 'development',
devtool: false,
output: {
filename: '[name].js',
path: path.join(__dirname, './dist')
},
plugins: [new HTMLWebpackPlugin()]
}
问题
HMR——模块热替换
- 开启HMR
devServer: {
hot: true, // 主要
open: true
},
- 启动webpack :
npx webpack serve
Tree-Shaking——删除无用代码
const path = require('path')
module.exports = {
entry: './src/index',
devtool: false,
output: {
filename: '[name].js',
path: path.join(__dirname, './dist')
},
mode: 'production', // 如果是 development 可以看到会有没有用到的代码
optimization: {
usedExports: true,
}
}
Loader组件
为了处理非标准的js资源,设计出资源翻译模块,用于将资源翻译为标准的js
配置
module: {
//rules(规则)
rules: [
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
},
]
}
三种loader的作用
- less-loader: 实现了 less ~> css 的转换
- css-loader: 将 CSS 包装成类似 module.exports = "${css}" 的内容,包装后的内容符合 JavaScript 语法
- style-loader: 将 CSS 模块包进 require 语句,并在运行时调用 injectStyle 等函数将内容注入到页面的 style 标签
特性
- 链式执行
- 支持异步执行
- 分 normal、pitch 两种模式
常见的loder
如何编写一个loader
Plugin组件
提升扩展性
const path = require("path");
//引入webpack模块(使用plugins)
const webpack = require('webpack');
//用来自动生成dist目录下的index.html页面代码
const htmlWebpackPlugin =require('html-webpack-plugin');
//用来丑化代码
const uglifyjsWebpackPlugin =require('uglifyjs-webpack-plugin');
module.exports = {
entry: './src/index',
mode: 'development',
devtool: false,
output: {
filename: '[name].js',
path: path.join(__dirname, './dist')
},
plugins:[
new htmlWebpackPlugin<p align=center>({</p>
//用于指定哪个模板来生成(优先寻找同级目录)
template:'index.html'
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.uglifyjsWebpackPlugin()
],
}
如何写一个plugin
插件围绕钩子展开; 钩子的核心信息:
- 时机: 编译过程的特定节点,Webpack 会以钩子形式通知插件此刻正在发生什么事情
- 上下文: 通过 tapable 提供的回调机制,以参数方式传递上下文信息
- 交互: 在上下文参数对象中附带了很多存在 side effect 的交互接口,插件可以通过这些接口改变