javascript - Vue.js/TypeScript 单文件组件库,可扩展并编译为 es5
我正在尝试创建一个使用 TypeScript 编写的 Vue SFC 组件库,以便在其他项目中只需安装它并在 SFC 中使用语法 “import {component} from ..” 导入即可,而不需要 Vue.use()。我更希望它能编译成 es5,包含类型声明,并且尽可能具有可扩展性(它可能包含超过 100 个组件,我不想要一个单一的打包文件)。我尝试过不同的方法:webpack、vue-cli 3、vue-sfc-rollup 和 rollup,而最后一种似乎最接近我希望的结果。最终的包结构如下:
dist/
|__@types/
| |__SampleComponent/
| | |__SampleComponent.vue.d.ts
| |__index.d.ts
|
|__node_modules/
| |__vue-runtime-helpers/ (contains normalize-component.mjs.js)
|
|__src/
|__SampleComponent/
| |__SampleComponent.vue.js
| |__SampleComponent.vue_rollup-plugin-vue=script.js
|__index.js (wrapper file)
问题是,正如我所说,.js 文件不是编译成 es5 而是 cjs(rollup 不能),组件的 .js 被拆分成两个文件,我不能放在 node-modules 文件夹外,看起来需要 normalize-component。这是我的配置文件:
rollup.config.js
import vue from "rollup-plugin-vue"
import typescript from "rollup-plugin-typescript2"
import renameExtensions from "@betit/rollup-plugin-rename-extensions"
import cleaner from "rollup-plugin-cleaner"
import commonjs from "rollup-plugin-commonjs"
import resolve from '@rollup/plugin-node-resolve';
// import del from 'rollup-plugin-delete'
import css from 'rollup-plugin-css-porter';
import sass from 'rollup-plugin-sass';
// import {terser} from "rollup-plugin-terser";
export default {
input: "./src/index.ts",
output: {
format: "cjs", // This is what tells rollup to use ES6 modules
dir: "dist",
sourcemap: true
},
external: ["vue", "vue-class-component", "vue-property-decorator", "tslib", "vue-runtime-helpers"],
plugins: [
cleaner({targets: ["dist"]}),
resolve(),
// This extension renames all .vue and .ts to .js
// (and updates the imports)
renameExtensions({
include: ["**/*.ts", "**/*.vue"],
mappings: {".vue": ".vue.js", ".ts": ".js"}
}),
vue({
css: true, // Dynamically inject css as a <style> tag
compileTemplate: true, // Explicitly convert template to render function
}),
typescript({
clean: true,
useTsconfigDeclarationDir: true
}),
commonjs(),
sass(),
css(),
/*terser({
output: {
ecma: 5,
},
}),*/ // minifies generated bundles
/*del({
targets: 'dist/index.d.ts',
hook: 'generateBundle'
})*/
],
// Prevents bundling, but doesn't rename files
preserveModules: true
}
package.json
import vue from "rollup-plugin-vue"
import typescript from "rollup-plugin-typescript2"
import renameExtensions from "@betit/rollup-plugin-rename-extensions"
import cleaner from "rollup-plugin-cleaner"
import commonjs from "rollup-plugin-commonjs"
import resolve from '@rollup/plugin-node-resolve';
// import del from 'rollup-plugin-delete'
import css from 'rollup-plugin-css-porter';
import sass from 'rollup-plugin-sass';
// import {terser} from "rollup-plugin-terser";
export default {
input: "./src/index.ts",
output: {
format: "cjs",
dir: "dist",
sourcemap: true
},
external: ["vue", "vue-class-component", "vue-property-decorator", "tslib", "vue-runtime-helpers"],
plugins: [
cleaner({targets: ["dist"]}),
resolve(),
// This extension renames all .vue and .ts to .js
// (and updates the imports)
renameExtensions({
include: ["**/*.ts", "**/*.vue"],
mappings: {".vue": ".vue.js", ".ts": ".js"}
}),
vue({
css: true, // Dynamically inject css as a <style> tag
compileTemplate: true, // Explicitly convert template to render function
}),
typescript({
clean: true,
useTsconfigDeclarationDir: true
}),
commonjs(),
sass(),
css(),
/*terser({
output: {
ecma: 5,
},
}),*/ // minifies generated bundles
/*del({
targets: 'dist/index.d.ts',
hook: 'generateBundle'
})*/
],
// Prevents bundling, but doesn't rename files
preserveModules: true
}
tsconfig.json
{
"compilerOptions": {
"module": "ES2015",
"target": "es5",
"downlevelIteration": true,
"resolveJsonModule": true,
"importHelpers": true,
"moduleResolution": "node",
"sourceMap": true,
// "outFile": "out.js",
"declaration": true,
"outDir": "./dist/lib",
"declarationDir": "./dist/@types",
"strict": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"types": [
"node"
],
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
],
"plugins": [
{
"name": "typescript-tslint-plugin"
}
]
},
"include": [
// Source
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
// Tests
"tests/**/*.ts",
"tests/**/*.tsx",
"src/browser/**/*.ts",
"src/site/images/typings.d.ts",
"src/site/images"
],
"exclude": [
"node_modules"
],
"files": [
"src/shims-vue.d.ts"
]
}
如果我的解释不够清楚,或者我的配置很混乱,提前表示抱歉。谢谢