Vue + 打字稿 + 汇总
Vue + Typescript + rollup
我正在尝试汇总 Vue 组件库,它是在 typescript + vue-属性-decorator 上编写的。我有几个 Vue 组件,插件 class 在一个单独的文件中,组件导入的位置:
import FormularioForm from '@/FormularioForm.vue'
import FormularioInput from '@/FormularioInput.vue'
import FormularioGrouping from '@/FormularioGrouping.vue'
测试套件 (vue-cli + jest) 工作正常,所有测试都通过了,但是在构建阶段,汇总模块路径解析工作不正确,因为组件的代码不存在于最终构建中。
rollup.config:
import autoExternal from 'rollup-plugin-auto-external'
import buble from '@rollup/plugin-buble'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import typescript from '@rollup/plugin-typescript'
import vue from 'rollup-plugin-vue'
export default {
input: 'src/index.ts',
output: [{
name: 'Formulario',
exports: 'default',
globals: {
'is-plain-object': 'isPlainObject',
'is-url': 'isUrl',
'nanoid/non-secure': 'nanoid',
},
sourcemap: false,
}],
external: ['nanoid/non-secure'],
plugins: [
commonjs(),
autoExternal(),
typescript({ sourceMap: false }),
vue({
css: true,
compileTemplate: true
}),
buble({
objectAssign: 'Object.assign',
}),
terser(),
]
}
tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"module": "es2015",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.js",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
package.json
{
"name": "@retailcrm/vue-formulario",
"version": "0.1.0",
"author": "RetailDriverLLC <integration@retailcrm.ru>",
"scripts": {
"build": "npm run build:esm & npm run build:umd & npm run build:iife & wait && echo \"Build complete:\nesm: $(gzip -c dist/formulario.esm.js | wc -c)b gzip\numd: $(gzip -c dist/formulario.umd.js | wc -c)b gzip\nmin: $(gzip -c dist/formulario.min.js | wc -c)b gzip\"",
"test": "NODE_ENV=test jest --config test/jest.conf.js",
"build:esm": "rollup --config build/rollup.config.js --format es --file dist/formulario.esm.js",
"build:iife": "rollup --config build/rollup.iife.config.js --format iife --file dist/formulario.min.js",
"build:size": "gzip -c dist/formulario.esm.js | wc -c",
"build:umd": "rollup --config build/rollup.config.js --format umd --file dist/formulario.umd.js",
"dev": "vue-cli-service serve --port=7872 examples/main.js",
"test:coverage": "NODE_ENV=test jest --config test/jest.conf.js --coverage",
"test:watch": "NODE_ENV=test jest --config test/jest.conf.js --watch"
},
"main": "dist/formulario.umd.js",
"module": "dist/formulario.esm.js",
"browser": {
"./sfc": "src/index.ts"
},
"unpkg": "dist/formulario.min.js",
"dependencies": {
"is-plain-object": "^3.0.0",
"is-url": "^1.2.4",
"nanoid": "^2.1.11",
"vue-class-component": "^7.2.3",
"vue-i18n": "^8.17.7",
"vue-property-decorator": "^8.4.2"
},
"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/plugin-transform-modules-commonjs": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-node-resolve": "^7.1.3",
"@rollup/plugin-typescript": "^6.0.0",
"@types/is-url": "^1.2.28",
"@types/jest": "^26.0.14",
"@types/nanoid": "^2.1.0",
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-plugin-eslint": "^4.3.1",
"@vue/cli-plugin-typescript": "^4.5.7",
"@vue/cli-service": "^4.5.4",
"@vue/component-compiler-utils": "^3.1.2",
"@vue/eslint-config-standard": "^5.1.2",
"@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^1.0.2",
"autoprefixer": "^9.7.6",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.5.1",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.1.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.3",
"flush-promises": "^1.0.2",
"jest": "^26.5.2",
"jest-vue-preprocessor": "^1.7.1",
"rollup": "^1.32.1",
"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-internal": "^1.0.4",
"rollup-plugin-multi-input": "^1.1.1",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-vue": "^5.1.7",
"ts-jest": "^26.4.1",
"typescript": "~3.9.3",
"vue": "^2.6.11",
"vue-jest": "^3.0.5",
"vue-runtime-helpers": "^1.1.2",
"vue-template-compiler": "^2.6.11",
"vue-template-es2015-compiler": "^1.9.1",
"watch": "^1.0.2"
},
"bugs": {
"url": "https://github.com/retailcrm/vue-formulario/issues"
},
"contributors": [
"Justin Schroeder <justin@wearebraid.com>"
],
"keywords": [
"vue",
"form",
"forms",
"validation",
"validate"
],
"license": "MIT",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/retailcrm/vue-formulario.git"
}
}
在控制台上捕获:
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
@/FormularioForm.vue (imported by src/Formulario.ts)
@/FormularioInput.vue (imported by src/Formulario.ts)
@/FormularioGrouping.vue (imported by src/Formulario.ts)
正在尝试找出合适的解决方案。
tsconfig 包含 paths
仅影响 TypeScript 编译器解析模块的方式,但不会替换 JS 输出中的别名导入路径。工具可以根据 paths
选项透明地处理文件,但这不应该是预期的。
bundle 的模块别名可以通过另一个 Rollup 插件解决,例如 @rollup/plugin-alias
。这揭示了最新 @rollup/plugin-typescript
与其他插件一起使用时导致处理错误的问题。
使此设置可行的一种方法是切换到另一个 TypeScript 插件,rollup-plugin-typescript2
:
import alias from '@rollup/plugin-alias';
import typescript from 'rollup-plugin-typescript2'
...
plugins: [
typescript({
check: false // disable typechecks if necessary
}),
vue({ css: true, compileTemplate: true }),
alias({ entries: [{ find:/^@\/(.+)/, replacement: './' }] }),
commonjs(),
autoExternal(),
buble({ objectAssign: 'Object.assign' }),
terser(),
]
可能不需要 Buble 插件,因为 TypeScript 能够处理 ES5 转译。
我正在尝试汇总 Vue 组件库,它是在 typescript + vue-属性-decorator 上编写的。我有几个 Vue 组件,插件 class 在一个单独的文件中,组件导入的位置:
import FormularioForm from '@/FormularioForm.vue'
import FormularioInput from '@/FormularioInput.vue'
import FormularioGrouping from '@/FormularioGrouping.vue'
测试套件 (vue-cli + jest) 工作正常,所有测试都通过了,但是在构建阶段,汇总模块路径解析工作不正确,因为组件的代码不存在于最终构建中。
rollup.config:
import autoExternal from 'rollup-plugin-auto-external'
import buble from '@rollup/plugin-buble'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import typescript from '@rollup/plugin-typescript'
import vue from 'rollup-plugin-vue'
export default {
input: 'src/index.ts',
output: [{
name: 'Formulario',
exports: 'default',
globals: {
'is-plain-object': 'isPlainObject',
'is-url': 'isUrl',
'nanoid/non-secure': 'nanoid',
},
sourcemap: false,
}],
external: ['nanoid/non-secure'],
plugins: [
commonjs(),
autoExternal(),
typescript({ sourceMap: false }),
vue({
css: true,
compileTemplate: true
}),
buble({
objectAssign: 'Object.assign',
}),
terser(),
]
}
tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"module": "es2015",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.js",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
package.json
{
"name": "@retailcrm/vue-formulario",
"version": "0.1.0",
"author": "RetailDriverLLC <integration@retailcrm.ru>",
"scripts": {
"build": "npm run build:esm & npm run build:umd & npm run build:iife & wait && echo \"Build complete:\nesm: $(gzip -c dist/formulario.esm.js | wc -c)b gzip\numd: $(gzip -c dist/formulario.umd.js | wc -c)b gzip\nmin: $(gzip -c dist/formulario.min.js | wc -c)b gzip\"",
"test": "NODE_ENV=test jest --config test/jest.conf.js",
"build:esm": "rollup --config build/rollup.config.js --format es --file dist/formulario.esm.js",
"build:iife": "rollup --config build/rollup.iife.config.js --format iife --file dist/formulario.min.js",
"build:size": "gzip -c dist/formulario.esm.js | wc -c",
"build:umd": "rollup --config build/rollup.config.js --format umd --file dist/formulario.umd.js",
"dev": "vue-cli-service serve --port=7872 examples/main.js",
"test:coverage": "NODE_ENV=test jest --config test/jest.conf.js --coverage",
"test:watch": "NODE_ENV=test jest --config test/jest.conf.js --watch"
},
"main": "dist/formulario.umd.js",
"module": "dist/formulario.esm.js",
"browser": {
"./sfc": "src/index.ts"
},
"unpkg": "dist/formulario.min.js",
"dependencies": {
"is-plain-object": "^3.0.0",
"is-url": "^1.2.4",
"nanoid": "^2.1.11",
"vue-class-component": "^7.2.3",
"vue-i18n": "^8.17.7",
"vue-property-decorator": "^8.4.2"
},
"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/plugin-transform-modules-commonjs": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-node-resolve": "^7.1.3",
"@rollup/plugin-typescript": "^6.0.0",
"@types/is-url": "^1.2.28",
"@types/jest": "^26.0.14",
"@types/nanoid": "^2.1.0",
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-plugin-eslint": "^4.3.1",
"@vue/cli-plugin-typescript": "^4.5.7",
"@vue/cli-service": "^4.5.4",
"@vue/component-compiler-utils": "^3.1.2",
"@vue/eslint-config-standard": "^5.1.2",
"@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^1.0.2",
"autoprefixer": "^9.7.6",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.5.1",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.1.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.3",
"flush-promises": "^1.0.2",
"jest": "^26.5.2",
"jest-vue-preprocessor": "^1.7.1",
"rollup": "^1.32.1",
"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-internal": "^1.0.4",
"rollup-plugin-multi-input": "^1.1.1",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-vue": "^5.1.7",
"ts-jest": "^26.4.1",
"typescript": "~3.9.3",
"vue": "^2.6.11",
"vue-jest": "^3.0.5",
"vue-runtime-helpers": "^1.1.2",
"vue-template-compiler": "^2.6.11",
"vue-template-es2015-compiler": "^1.9.1",
"watch": "^1.0.2"
},
"bugs": {
"url": "https://github.com/retailcrm/vue-formulario/issues"
},
"contributors": [
"Justin Schroeder <justin@wearebraid.com>"
],
"keywords": [
"vue",
"form",
"forms",
"validation",
"validate"
],
"license": "MIT",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/retailcrm/vue-formulario.git"
}
}
在控制台上捕获:
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
@/FormularioForm.vue (imported by src/Formulario.ts)
@/FormularioInput.vue (imported by src/Formulario.ts)
@/FormularioGrouping.vue (imported by src/Formulario.ts)
正在尝试找出合适的解决方案。
tsconfig 包含 paths
仅影响 TypeScript 编译器解析模块的方式,但不会替换 JS 输出中的别名导入路径。工具可以根据 paths
选项透明地处理文件,但这不应该是预期的。
bundle 的模块别名可以通过另一个 Rollup 插件解决,例如 @rollup/plugin-alias
。这揭示了最新 @rollup/plugin-typescript
与其他插件一起使用时导致处理错误的问题。
使此设置可行的一种方法是切换到另一个 TypeScript 插件,rollup-plugin-typescript2
:
import alias from '@rollup/plugin-alias';
import typescript from 'rollup-plugin-typescript2'
...
plugins: [
typescript({
check: false // disable typechecks if necessary
}),
vue({ css: true, compileTemplate: true }),
alias({ entries: [{ find:/^@\/(.+)/, replacement: './' }] }),
commonjs(),
autoExternal(),
buble({ objectAssign: 'Object.assign' }),
terser(),
]
可能不需要 Buble 插件,因为 TypeScript 能够处理 ES5 转译。