阅读这篇文章前,请先了解 element-plus源码分析-构建流程
full-bundle 是打包给浏览器的环境使用的,入口为 packages/element-plus/index.ts
,出口为 dist/element-plus/dist/index.full(.min).(mjs|js)
async function buildFullEntry(minify: boolean) {
const bundle = await rollup({
input: path.resolve(epRoot, 'index.ts'),
plugins: [
ElementPlusAlias(),
vue({
isProduction: true
}),
nodeResolve({
extensions: ['.mjs', '.js', '.json', '.ts'],
}),
commonjs(),
esbuild({
minify,
sourceMap: minify,
target,
}),
replace({
'process.env.NODE_ENV': JSON.stringify('production'),
// options
preventAssignment: true,
}),
filesize(),
],
external: await generateExternal({ full: true }),
})
await writeBundles(bundle, [
{
format: 'umd',
file: path.resolve(
epOutput,
'dist',
formatBundleFilename('index.full', minify, 'js')
),
exports: 'named',
name: 'ElementPlus',
globals: {
vue: 'Vue',
},
sourcemap: minify,
banner,
},
{
format: 'esm',
file: path.resolve(
epOutput,
'dist',
formatBundleFilename('index.full', minify, 'mjs')
),
sourcemap: minify,
banner,
},
])
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
来看看 ElementPlusAlias
插件做了什么事情:
import { EP_PKG, EP_PREFIX } from '../utils/constants'
import type { Plugin } from 'rollup'
export function ElementPlusAlias(): Plugin {
const THEME_CHALK = `${EP_PREFIX}/theme-chalk`
return {
name: 'element-plus-alias-plugin',
resolveId(id, importer, options) {
if (!id.startsWith(EP_PREFIX)) return
if (id.startsWith(THEME_CHALK)) {
return {
id: id.replaceAll(THEME_CHALK, `${EP_PKG}/theme-chalk`),
external: 'absolute',
}
}
return this.resolve(id, importer, { skipSelf: true, ...options })
},
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
这里处理 [resolveId](https://www.rollupjs.com/guide/plugin-development#resolveid)
钩子,rollup 中模块(文件)的id就是文件地址,所以类似resolveID这种就是解析文件地址的意思,我们可以返回我们想返回的文件id(也就是地址,相对路径、决定路径)来让rollup加载。EP_PREFIX的值是 @element-plus
, EP_PKG的值是 element-plus
,也就是不是 @element-plus
的模块不打包,并且遇到的模块 @element-plus/theme-chalk
名称改为 element-plus/theme-chalk
。也就是将js中的 样式文件的路径改为实际打包后的文件引用地址。(不过貌似 element-plus 源码中找不到那个 @element-plus/theme-chalk路径)
然后是 import vue from '@vitejs/plugin-vue'
这个是导入 vite 的 vue 插件,真是烦单从这两行代码只能猜是用于 vite 解析 vue 文件的,而文档几乎啥也没写(需要的话只能去看源码了),就直接这样用吧前端真是乱,工程实践很多都是这样。
nodeResolve
这个 rollup-plugin-node-resolve (opens new window) 插件可以告诉 Rollup 如何查找外部模块。
目前, npm 中的大多数包都是以 CommonJS 模块的形式出现的。在它们更改之前,我们需要将 CommonJS 模块转换为 ES2015 供 Rollup 处理。这个 rollup-plugin-commonjs (opens new window) 插件就是用来将 CommonJS 转换成 ES2015 模块的。
esbuild
是将 TS/ESNext 编译成 ES6.
@rollup/plugin-replace
是在打包的过程中将目标字符串替换。
rollup-plugin-filesize
是用来显示打包后的文件大小的插件。
来看 rollup 不打包进的依赖包:
export const generateExternal = async (options: { full: boolean }) => {
const { dependencies, peerDependencies } = await getPackageDependencies(
epPackage
)
return (id: string) => {
const packages: string[] = peerDependencies
if (!options.full) {
packages.push('element-plus/theme-chalk')
// dependencies
packages.push('@vue', ...dependencies)
}
return [...new Set(packages)].some(
(pkg) => id === pkg || id.startsWith(`${pkg}/`)
)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上面的意思是:将epPackage对应的package.json的上某些相关依赖不打包。
行了,你开始打包吧。