小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
Rollup从0到1上手前端组件库开发 | VUE组件编译
上文回顾
- Rollup从0到1上手前端组件库开发 | 起步
- Rollup从0到1上手前端组件库开发 | 模块构建
- Rollup从0到1上手前端组件库开发 | tree-shaking 机制
- Rollup从0到1上手前端组件库开发 | external属性
- Rollup从0到1上手前端组件库开发 | CJS插件
- Rollup从0到1上手前端组件库开发 | 常用插件
通过上文的讲解, 我们目前已经完成了js文件的解析和编译, 下面我们一起研究一下如何解析和编译vue文件
尝试一下使用Rollup打包Vue文件
-
首先,创建一个简单的 Vue3 组件
在src 目录下创建 Test.vue文件
<template>
<div class="test">{{message}}</div>
</template>
<script>
export default {
name: "TestComponent",
setup() {
const message = 'hello rollup'
return {
message
}
}
}
</script>
<style scoped lang="scss">
.test {
color: blue;
}
</style>
- 在 index.js 中定义组件
import Test from './Test.vue'
export default function (Vue) {
Vue.component(Test.name, Test)
}
- 直接通过
npm run build来构建
npm run build
> payfun.rollbear.view@1.0.0 build
> rollup -c rollup.config.dev.js
/Users/pm/adtech/pc/payfun.rollbear.view/src/index.js
/Users/pm/adtech/pc/payfun.rollbear.view/src/index.js → dist/payfun.rollbear.dev.js, dist/payfun.rollbear.dev.es.js...
# 报错了~!
# [!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
# src/Test.vue (1:0)
Test.vue 文件在Rollup打包的默认情况下是不能支持的, 需要vue插件才能支持
接下来我们继续研究 Rollup 如何支持 vue 文件打包
安装插件
yarn add rollup-plugin-vue -D
"rollup-plugin-vue": "^6.0.0" #6.0.0 可以支持 vue3 组件打包编译
配置文件中添加对 .vue 文件的支持
vim rollup.config.dev.js
const path = require('path')
const resolve = require("rollup-plugin-node-resolve")
const commonjs = require('rollup-plugin-commonjs')
const babel = require('rollup-plugin-babel')
const json = require('rollup-plugin-json')
// 这里 引入 vue 插件
const vue = require('rollup-plugin-vue')
const inputPath = path.resolve(__dirname, "./src/index.js") // 输入路径
const outputUmdPath = path.resolve(__dirname, "./dist/payfun.rollbear.dev.js") // 输出路径
const outputEsPath = path.resolve(__dirname, "./dist/payfun.rollbear.dev.es.js") // 输出路径
console.log(inputPath)
module.exports = {
input: inputPath,
output: [
{
file: outputUmdPath, // 输出路径
format: 'umd', // 输出的模块协议 umd
name: "payfunRollbear" // 模块名称
},
{
file: outputEsPath, // 输出路径
format: 'es', // 输出的模块协议 es
name: "payfunRollbear" // 模块名称
}
],
plugins: [
resolve(),
commonjs(),
babel({
exclude: 'node_modules/**', // 指定哪些文件夹时不进行babel编译的
}),
json(),
vue(), // 使用Vue插件
],
external: ['decimal.js'], //表示哪些模块是外部引用, 即使开启了 resolve 这里面的模块仍然是外部引用
}
再吃尝试一下 yarn build
npm run build
> rollbear.view@1.0.0 build
> rollup -c rollup.config.dev.js
[!] Error: rollup-plugin-vue requires @vue/compiler-sfc to be present in the dependency tree.
结果发现仍然报错, 从错误信息中我们发现 rollup-plugin-vue 需要 @vue/compiler-sfc的依赖
安装 @vue/compiler-sfc
yarn add @vue/compiler-sfc -D
安装完成后我们不需要手动去使用, rollup-plugin-vue 会自动去使用
划重点!!! Rollup 的 plugin 是有序的! vue要在前面调用 , 否则就会报错
plugins: [
vue(), // vue 放在最前面
resolve(),
commonjs(),
babel({
exclude: 'node_modules/**', // 指定哪些文件夹时不进行babel编译的
}),
json(),
postcss({
plugins:[]
})
],
再次 yarn build
yarn build
[!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
src/Test.vue?vue&type=style&index=0&id=07bdddea&scoped=true&lang.scss (2:0)
1:
2: .test {
^
3: color: blue;
4: }
Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
此时我们发现 style 文件不能解析, 当前可以解析 .vue 文件, 但是 style部分无法识别
通过 rollup-plugin-postcss 插件 来解决 style 无法识别的问题
yarn add rollup-plugin-postcss -D
将 postcss 加到 配置中
// ...
const vue = require('rollup-plugin-vue')
// 添加 postcss 插件
const postcss = require('rollup-plugin-postcss')
// ...
module.exports = {
// ...
plugins: [
resolve(),
commonjs(),
babel({
exclude: 'node_modules/**', // 指定哪些文件夹时不进行babel编译的
}),
json(),
vue(),
postcss({
plugins:[]
})
],
// ...
}
//...
再次执行 yarn build
又报错了~!
[!] (plugin postcss) Error: You need to install one of the following packages: "node-sass", "sass" in order to process SASS files
这里发现我们需要安装 node-sass 或 sass 两者之一
安装 sass (dart-sass)
yarn add sass -D
再次编译
created rollbear.dev.js, rollbear.dev.es.js in 2.8s
✨ Done in 5.00s.
终于成功啦!
查看ES模块编译结果
import { openBlock, createElementBlock, toDisplayString } from 'vue';
var script = {
name: "TestComponent",
setup: function setup() {
var message = 'hello rollup';
return {
message: message
};
}
};
var _hoisted_1 = {
"class": "test"
};
function render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("div", _hoisted_1, toDisplayString($setup.message), 1
/* TEXT */
);
}
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css_248z = ".test[data-v-07bdddea] {\n color: blue;\n}";
styleInject(css_248z);
script.render = render;
script.__scopeId = "data-v-07bdddea";
script.__file = "src/Test.vue";
function index (Vue) {
Vue.component(script.name, script);
}
export { index as default };
因为我们用了 external: ['vue'], 所以vue源码不会打包到我们的文件当中~
至此 Vue 文件的编译就实现了~!
总结
编译 .vue 组件的步骤
- 安装并配置 vue 插件
yarn add rollup-plugin-vue -D - 安装vue插件依赖
yarn add @vue/compiler-sfc -D- 强调 rollup 的plugin 是有执行顺序的 , vue 要放在最前面调用
- 安装 postcss 插件用来支持 style
- 安装 sass 用来支持 sass 预处理器
警告问题解决
在成功编译 .vue 文件是 我们发现 terminal 上有两个黄色的警告
(!) Unresolved dependencies
# vue没用到,可以无视
(!) Missing global variable name
Use output.globals to specify browser global variable names corresponding to external modules
vue (guessing 'vue')
# 解决方法: output 中添加 globals
output: [
{
file: outputUmdPath, // 输出路径
format: 'umd', // 输出的模块协议 umd
name: "payfunRollbear", // 模块名称
globals: {
vue: 'Vue'
}
},
]