解决vite模块化打包

在 vite 环境下开发时,默认是试用 ESM 打包,但是当我开发一个嵌入式应用就需要能做到闭包以防止变量冲突等问题,这个时候就要切换打包方式了,经过我不断的翻看文档,发现只需要在build.rollupOptions.output.format 配置iife即可,因为 vite 底层试用 rollup 构建,所以我们需要告诉 rollup 我们需要使用什么方式来构建。

output.format

Type: string
CLI: -f/–format
Default: “es”

Specifies the format of the generated bundle. One of the following:

  • amd

    Asynchronous Module Definition, used with module loaders like RequireJS

  • cjs

    CommonJS, suitable for Node and other bundlers (alias: commonjs)

  • es

    Keep the bundle as an ES module file, suitable for other bundlers and inclusion as a <script type=module> tag in modern browsers (alias: esm, module)

  • iife – A self-executing function, suitable for inclusion as a <script> tag. (If you want to create a bundle for your application, you probably want to use this.). “iife” stands for “immediately-invoked Function Expression

  • umd – Universal Module Definition, works as amd, cjs and iife all in one

  • system – Native format of the SystemJS loader (alias: systemjs)

当我们设置为iife后还需要为其指定一个模块名称, 也就是 name。

1
2
3
4
5
6
7
export default {
...,
output: {
format: 'iife',
name: 'MyBundle'
}
};

elmentPlus 命名空间

打包以后可能会与原本存在的 element 的样式存在冲突, 所以我们可以给 element 样式添加命名空间, 在app.vue中使用el-config-provider组建包裹住所有组件。

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<!-- 命名空间防止elment样式冲突 -->
<el-config-provider namespace="anzhiyu">
<main class="fcircle_page">
<FishPond />

<Transition name="anzhiyu">
<ManagePanel v-if="managePanelShow" />
</Transition>
</main>
</el-config-provider>
</template>

由于elmentPlus采用sass作为 css 预处理器,所以打包的时候要使用 sass 预处理,所以需要安装有 sass,

新建src/assets/el.scss

1
2
3
4
// we can add this to custom namespace, default is 'el'
@forward "element-plus/theme-chalk/src/mixins/config.scss" with (
$namespace: "anzhiyu"
);

修改 vite.config.ts的配置,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "./src/assets/el.scss" as *;`,
},
},
},
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
}),
],
....
})

完整配置

1
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
56
57
58
59
60
61
62
63
/*
* @Description: vite配置文件
* @Author: 安知鱼
* @Email: anzhiyu-c@qq.com
* @Date: 2022-10-31 13:27:51
* @LastEditTime: 2022-11-10 21:08:52
* @LastEditors: 安知鱼
*/
import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

// https://vitejs.dev/config/
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "./src/assets/el.scss" as *;`,
},
},
},
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
}),
],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
build: {
target: ["chrome58"],
minify: "terser",
rollupOptions: {
output: {
format: "iife",
name: "output.js",
},
},
sourcemap: false,
assetsInlineLimit: 4096,
terserOptions: {
compress: {
// 打包自动删除console
drop_console: true,
drop_debugger: true,
},
keep_classnames: true,
toplevel: true,
ie8: true,
},
},
});