温馨提示: 先别替换 ant-design-vue 中的 moment 为 dayjs, 有bug, date-picker会坏掉,等作者修好再换
本项目的技术栈是:vite vue3 ant-desing-vue
。
项目中需要用到的ant-desing-vue
UI 组件依赖moment
,我看官网提示有插件可以改成dayjs
,可以使整个包小一点,看了antd-dayjs-webpack-plugin
的代码后发现没有针对vite ant-desing-vue
的,就跃跃欲试想写一个vite-plugin-vue-ant-desing-vue-dayjs
插件,专门用在vite vue3 ant-desing-vue
项目中。后面其实发现没必要,当然,写完才发现-_-||
主要问题
叠了 3 个 debuff 导致运行时出问题
- 由于我 fork 了一部分
antd-dayjs-webpack-plugin
代码,内部是module.exports
- 同时入口文件里是直接
export default vitePluginVueAntDVueDayjs(Options={}) {...}
- 而且是直接
yarn add git+ssh://git@github.com:xxx/some-project.git --dev
,这个some-project
就是写的插件,package.json
里暴露的直接是main: src/index.js
,
第一次写插件,心情十分激动结果刚运行就报错,搜了一下原来是 node 环境里不能直接加载ES6
模块。。。于是我重新看了一次 es6 文档node 环境如何加载es6模块
,然后查了一下@vite/plugin-vue
的解决办法
解决方案
- 完全采用 cjs 模块方式编写,一水儿的
module.export
-> 针对入口文件非打包后的插件。如package.json中的main: src/index.js
- 将 es6 模块打包编译成 node 模块(@vite/plugin-vue)就是这么做的:
esbuild src/index.ts --bundle --platform=node --target=node12 --external:@vue/compiler-sfc --outfile=dist/index.js
-> 完全使用 es6 模块编写插件,然后使用打包后的 cjs 模块, package.json中的main: dist/index.js
没必要写是因为直接配置即可
1 2 3 4 5 6 7 8
| { resolve: { alias: { moment: 'dayjs' } }, }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import dayjs from 'dayjs' import isSameOrBefore from 'dayjs/plugin/isSameOrBefore' import isSameOrAfter from 'dayjs/plugin/isSameOrAfter' import advancedFormat from 'dayjs/plugin/advancedFormat' import customParseFormat from 'dayjs/plugin/customParseFormat' import weekday from 'dayjs/plugin/weekday' import weekOfYear from 'dayjs/plugin/weekOfYear' import isMoment from 'dayjs/plugin/isMoment' import localeData from 'dayjs/plugin/localeData' import localizedFormat from 'dayjs/plugin/localizedFormat' import 'dayjs/locale/zh-cn'
dayjs.extend(isSameOrBefore) dayjs.extend(isSameOrAfter) dayjs.extend(advancedFormat) dayjs.extend(customParseFormat) dayjs.extend(weekday) dayjs.extend(weekOfYear) dayjs.extend(isMoment) dayjs.extend(localeData) dayjs.extend(localizedFormat) dayjs.locale('zh-cn')
|
插件步骤
如果要写也不是不行:看上面的配置步骤即可知道思路,可参考项目vite-plugin-vue-antd-dayjs
第一种: 使用非打包插件
有个直接的好处,安装后可以直接修改包文件来测试代码逻辑是否正确,即改即用,我当时采用的就是这种写法
1. 新建项目
1 2 3 4 5
| |-- src |----|--index.js |-- package.json |-- README.md
|
2. package.json 配置
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
| { "name": "vite-plugin-xxx", "version": "1.0.0", "description": "Description of the vite-plugin-xxx", "main": "src/index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": ["vite-plugin", "vite-plugin-vue", "rollup-plugin", "xxx"], "engines": { "node": ">=12.0.0" }, "devDependencies": { "dayjs": "*" }, "peerDependencies": { "dayjs": "*" }, "homepage": "", "bugs": { "url": "" }, "repository": { "type": "git", "url": "" }, "author": "your Name", "license": "" }
|
3. 入口文件
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
| module.exports = function VitePluginVueXXX(Options = {}) { const virtualFile = "@virtual-file"; return { name: "vite-plugin-vue-xxx", enforce: "pre", config: () => ({ "resolve.alias": { moment: "dayjs", }, }), configResolved(resolvedConfig) { config = resolvedConfig; }, resolveId(id) { if (id === virtualFile) { console.log("resolveid id test", id); return id; } }, load(id) { if (id === virtualFile) { return `const isMoment = require('dayjs/plugin/isMoment'); dayjs.extend(isMoment);module.exports = {isMoment}`; } }, }; };
|
4. 安装 没有发布的包文件
1 2 3 4
| yarn add dayjs
yarn add git+ssh://git@github.com:xxx.git --dev
|
1 2 3 4 5 6 7 8 9 10 11
|
const vitePluginVueForAntdDayjs = require('vite-plugin-vue-antd-dayjs') { plugins: [vue(),vitePluginVueForAntdDayjs()], resolve: { alias: { moment: 'dayjs' } }, }
|
5. 在 main.js 里引入虚拟文件即可
1 2 3 4 5
|
import isMoment from "@virtual-file";
import "@virtual-file";
|
启动项目: yarn dev
, vite 打包会发现有提示:[vite] new dependencies found: dayjs/plugin/isSameOrAfter, dayjs/plugin/advancedFormat, dayjs/plugin/customParseFormat, dayjs/plugin/weekday, dayjs/plugin/weekYear, dayjs/plugin/weekOfYear, dayjs/plugin/isMoment, dayjs/plugin/localeData, dayjs/plugin/localizedFormat, dayjs/locale/zh-cn, updating...
说明已经成功引入
6. 打包比较前后包的差异
第二种:使用打包后的插件
步骤跟上面的差不多,只是写的时候使用 es6 模块,多一步打包&入口文件有点不同,可参考项目vite-plugin-antd-vue-ts
packgae.json 的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| { "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build:boundle": "`esbuild src/index.ts --bundle --platform=node --target=node12 --external:dayjs --outfile=dist/index.js" }, "dependencies": { "esbuild": "*" }, "devDependencies": { "dayjs": "*" }, "peerDependencies": { "dayjs": "*" } }
|
入口文件
1
| export default function VitePluginVueXXX(Options = {}) {}
|
- 执行打包命令
- 配置
vite.config.js
& 在main.js
引入文件步骤同上
如果要实现在入口文件的引用方式为 import someplugin from 'path/to/all-plugin-file-name'
,在插件内使用 export default
和 module.exports
是一样的效果