按照 Vue 2 组件打包并发布到 npm 的方法配置项目后,项目在实际开发过程中,随着代码写法的多样性增加而遇到的各种打包问题,本文将予以逐一解决:
本文目录
同时导出多个组件
样式表 import 问题解决
Json 文件 import 问题解决
"@"路径别名无法识别的问题
??, ?. 等运算符无法编译的问题解决
jsx 语法的支持
支持 TypeScript
同时导出多个组件
修改 wrapper.js 即可
import component1 from './components/MyComponent1.vue';
import component2 from './components/MyComponent2.vue';
export function install(Vue) {
if (install.installed) return;
install.installed = true;
Vue.component('MyComponent1', component1);
Vue.component('MyComponent2', component2);
}
...
// export default component;
export {
component1 as MyComponent1,
component2 as MyComponent2,
}
样式表 import 问题解决
<script>
import "../scss/common.scss";
...
</script>
如上代码所示,如果在 .vue 页面的 script 标签间 import 样式表(或者在 .js 文件中 import 样式表),会在打包时报错,如下
关键报错信息:SyntaxError: Unexpected token
针对 .scss, .sass 和 .css 样式表的解决办法如下
安装 rollup-plugin-scss 插件
npm i rollup-plugin-scss -D
修改 rollup.config
...
import scss from 'rollup-plugin-scss';
export default {
...
plugins: [
commonjs(),
scss({ insert: true }),
image(),
...
],
};
Json 文件 import 问题解决
<script>
...
import info from "../data/info.json";
export default {
...
mounted() {
console.log("读取 json 文件内容 :>> ", info);
},
};
</script>
如上代码所示,引入 .json 文件会导致打包报错:
关键报错信息:SyntaxError: Unexpected token
解决方法如下
安装 @rollup/plugin-json 插件
npm i @rollup/plugin-json -D
修改 rollup.config
...
import json from '@rollup/plugin-json';
export default {
...
plugins: [
commonjs(),
scss({ insert: true }),
image(),
json(),
...
],
};
"@"路径别名无法识别的问题
如下,使用了 Vue 原生支持的 @ 作为路径别名
<script>
import LOGO from "@/assets/logo.png";
import "@/scss/common.scss";
import info from "@/data/info.json";
...
</script>
但打包时会报警告
关键警告信息:Unresolved dependencies
解决方法如下
安装 @rollup/plugin-alias 插件
npm i @rollup/plugin-alias -D
修改 rollup.config
...
import { fileURLToPath } from 'url';
import path from 'path';
import alias from '@rollup/plugin-alias';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRootDir = path.resolve(__dirname, '..');
export default {
...
plugins: [
commonjs(),
alias({
entries: [{
find: '@',
replacement: path.resolve(projectRootDir, 'src'),
}]
}),
scss({ insert: true }),
image(),
json(),
...
],
};
??, ?. 等运算符无法编译的问题解决
如下,代码中出现空值合并运算符(??)或可选链运算符(?.)时
<script>
...
export default {
...
mounted() {
let x;
const y = x ?? 1;
},
};
</script>
出现如下报错
关键报错信息:SyntaxError: Unexpected token
解决此问题,要么把 ?? 和 ?. 的语法替换为其它等效的算法
要么如下所示,把本来所用的 @rollup/plugin-buble 插件替换为 @rollup/plugin-babel 插件
安装 @rollup/plugin-babel 插件
npm i @rollup/plugin-babel -D
修改 rollup.config
...
import { babel } from '@rollup/plugin-babel';
...
export default {
...
plugins: [
...
vue({
css: true, // Dynamically inject css as a <style> tag
compileTemplate: true, // Explicitly convert template to render function
}),
// buble({
// objectAssign: true,
// transforms: {
// asyncAwait: false,
// forOf: false,
// }
// }), // Transpile to ES5
babel({
babelHelpers: 'runtime',
exclude: 'node_modules/**'
}),
],
};
jsx 语法的支持
<template>
<div class="component my-component">
<img :src="logoSrc" />
<Title />
</div>
</template>
<script>
...
const Title = {
name: "title",
render() {
return <span>标题</span>; // jsx 语法
},
};
export default {
components: { Title },
...
};
</script>
以上写法将导致打包出错:
关键报错信息:(plugin commonjs--resolver) RollupError: Expression expected
解决方法如下
安装 unplugin-vue-jsx 插件
npm i unplugin-vue-jsx -D
修改 rollup.config
...
import VueJsx from 'unplugin-vue-jsx/rollup';
...
export default {
...
plugins: [
commonjs({ exclude: 'src/**' }), // 需要排除掉包含 jsx 语法的文件,否则 VueJsx 无效,原因未知
...
VueJsx({ version: 2 }),
vue({
css: true, // Dynamically inject css as a <style> tag
compileTemplate: true, // Explicitly convert template to render function
}),
...
],
};
支持 TypeScript
如果本项目已配置为支持 TypeScript 的 Vue2 项目,则在打包时会报错
关键报错信息:Note that you need plugins to import files that are not JavaScript
解决方法如下
安装 rollup-plugin-typescript2 插件
npm i rollup-plugin-typescript2 -D
注:为什么不使用 @rollup/plugin-typescript ?请参考 vue.js - Error: Unexpected token (Note that you need plugins to import files that are not JavaScript) rollup vue package - Stack Overflow
修改 rollup.config
...
import typescript2 from 'rollup-plugin-typescript2';
...
export default {
...
plugins: [
typescript2({
useTsconfigDeclarationDir: true,
// tsconfigOverride: { // 是否覆盖 tsconfig.json 的设置
// compilerOptions: {
// declaration: false,
// }
// }
}),
commonjs({ exclude: 'src/**' }),
...
],
};
如果希望输出类型说明文件(d.ts),则增加以下两步
修改 tsconfig.json
{
"compilerOptions": {
...
"sourceMap": false,
"declaration": true,
"declarationDir": "dist/types",
"baseUrl": ".",
...
},
...
}
修改 package.json
{
...
"license": "MIT",
"main": "dist/my-component.umd.js",
"module": "dist/my-component.esm.js",
"unpkg": "dist/my-component.min.js",
"types": "dist/types/main.d.ts",
...
}
如果需要生成 source map,则如下配置
修改 tsconfig.json
...
export default {
...
output: {
name: 'MyComponent',
exports: 'named',
sourcemap: true,
},
...
};
即在 output 中增加 sourcemap: true
tsconfig.json 中的配置项 sourceMap 最好也写成 "sourceMap": true,虽然在本案例中并不会形成实质区别
衍生问题解决:
如下,按 ts 风格编写的 Vue 组件中,引入了 vue
<script lang="ts">
import Vue from "vue";
...
export default Vue.extend({
...
});
</script>
打包时会报如下警告
关键警告信息:Unresolved dependencies
消除警告方法如下
安装 @rollup/plugin-node-resolve 插件
npm i @rollup/plugin-node-resolve -D
修改 rollup.config
...
import resolve from '@rollup/plugin-node-resolve';
...
export default {
...
plugins: [
...
scss({ insert: true }),
image(),
json(),
resolve(),
VueJsx({ version: 2 }),
...
],
};