以下皆为拉勾教育课件内笔记
模块解析(resolve)
resolve
resolve 可以配置 Webpack 中模块的解析规则。
详情查看:https://www.webpackjs.com/configuration/resolve/
module.exports = {
// ......
// 模块解析规则
resolve: {
// 引⼊模块时,可以省略哪些后缀名
extensions: ['.js', '.vue', '.json', '.less'],
// 配置模块解析的路径别名
alias: {
'@': resolve('src'),
},
// 指定模块默认加载的路径
modules: [resolve(__dirname, '../node_modules'), 'node_modules']
},
// ......
}
正常引入
import './src/css/main.less'
别名引入
import '@/css/main.less'
省略后缀引入
import '@/css/main'
排除依赖打包(externals)
排除打包依赖,一些第三方的包(例如:jQuery)已经处理好了,不需要参与 webpack 打包。此时,我们可以将其排除在外。这样可以减少打包体积,提高打包效率。
排除
module.exports = {
// ....
externals: {
'jquery': 'jQuery'
},
// ....
}
排除打包之后,还要引入。否则报错
CDN 引入
在模板中通过 script 引入 jQuery
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
模块联邦
简介
模块联邦是 Webpack 5 推出的⼀个新特性。它是⼀种模块共用机制,允许本地调用远程的模块。
详情查看:https://webpack.js.org/concepts/module-federation/
使用
创建两个应用
创建两个应⽤ app1 和 app2
mkdir app1
cd app1
npm init -y
npm install webpack webpack-cli html-webpack-plugin webpack-dev-server -D
然后创建 src 目录,并创建入口文件 ./src/index.js 和模板文件 ./src/index.html,app2 按照相同的方式创建。
App1 声明共用模块
声明模块
// Sitename.js
// 站点名称
export default (name) => {
console.log('来⾃ app1 的共⽤模块')
const element = document.createElement('h2')
element.textContent = name
return element
}
在入口文件中引入
import sitename from './Sitename.js'
const title = sitename('应⽤ A')
document.body.append(title)
在 webpack.config.js 中,使用联邦模块插件
const Mfp = require('webpack').container.ModuleFederationPlugin;
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 导⼊模块联邦插件
const Mfp = require('webpack').container.ModuleFederationPlugin;
module.exports = {
// mode ⼯作模式
mode: 'development',
// ⼊⼝
entry: './src/index.js',
// 出⼝
output: {
path: resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
// 模块
module: {
rules: [
]
},
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new Mfp({
// 对外提供的打包后的⽂件名(引⼊时使⽤)
filename: 'app1.js',
// 当前应⽤模块名称
name: 'app1',
// 暴露模块
exposes: {
// 名称: 代码路径
'./Sitename': './src/Sitename.js',
// './Carousel': './src/Carousel.js',
// './Pagination': './src/Pagination.js'
}
})
],
// 服务器
devServer: {
contentBase: resolve(__dirname, 'dist'),
port: 3001,
open: true
}
}
App2 引入共用模块
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 模块联邦
const Mfp = require('webpack').container.ModuleFederationPlugin
module.exports = {
// mode ⼯作模式
mode: 'development',
// ⼊⼝
entry: './src/index.js',
// 出⼝
output: {
path: resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
// 模块
module: {
rules: [
]
},
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new Mfp({
// 导⼊模块
remotes: {
// 导⼊后给模块起个别名:“微应⽤名称@地址/导出的⽂件名”
appone: 'app1@http://localhost:3001/app1.js'
},
// 应⽤ B 也可以对外提供模块,因此,也可以配置 filename 和 name
filename: 'app2.js',
// 应⽤名称,当前模块⾃⼰的名字
name: 'app2',
})
],
// 服务器
devServer: {
contentBase: resolve(__dirname, 'dist'),
port: 3002,
open: true
}
}
在 App2 中使用 App1 的模块
// app2/src/index.js
// 调⽤ app1 中的模块
import('appone/Sitename').then(res => {
// res.default()
const title = res.default('应⽤ B')
document.body.append(title)
})
import("appone/Carousel").then((res) => {
res.default()
});
import("appone/Pagination").then((res) => {
res.default()
});