尝试使用 rollup 和 vueJs 3 构建 vue 组件库
Posted
技术标签:
【中文标题】尝试使用 rollup 和 vueJs 3 构建 vue 组件库【英文标题】:Trying to build vue component library using rollup and vueJs 3 【发布时间】:2021-02-02 21:42:51 【问题描述】:我正在尝试使用 rollup 和 vuejs 创建一个 vue 组件库。它与 vue2 一起工作,但无法用 vue3 解析 css。我已经升级了 package.json 中的依赖
package.json
"name": "vue2tslibrary",
"version": "0.1.59",
"scripts":
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"build:js": "rimraf dist && rollup -c && rollup -c --environment MINIFY"
,
"sideEffects": [
"*.css",
"*.scss"
],
"files": [
"dist",
"src"
],
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"unpkg": "dist/vueslib.min.js",
"dependencies":
"@mathieustan/vue-datepicker": "^0.2.8",
"core-js": "^3.6.5",
"date-fns": "^2.16.1",
"vue": "^3.0.1",
"vue-router": "^4.0.0-beta.13",
"vue-slider-component": "^4.0.0-beta.2",
"vue-template-compiler": "^2.6.12",
"vuex": "^4.0.0-beta.4"
,
"devDependencies":
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
"@rollup/plugin-alias": "2.2.0",
"@rollup/plugin-babel": "^5.2.1",
"@rollup/plugin-commonjs": "^15.1.0",
"@rollup/plugin-image": "^2.0.5",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-url": "^5.0.1",
"@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.1",
"@vue/eslint-config-standard": "^5.1.2",
"@vue/eslint-config-typescript": "^5.0.2",
"autoprefixer": "^9.8.6",
"cssnano": "^4.1.10",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^6.2.2",
"node-sass": "^4.14.1",
"postcss": "^8.1.1",
"postcss-calc": "^7.0.3",
"postcss-color-function": "^4.1.0",
"postcss-cssnext": "^3.1.0",
"postcss-discard-comments": "^4.0.2",
"postcss-discard-empty": "^4.0.1",
"postcss-discard-unused": "^4.0.1",
"postcss-each": "^0.10.0",
"postcss-extend-rule": "^3.0.0",
"postcss-import": "^12.0.1",
"postcss-mixins": "^6.2.3",
"postcss-nested": "^4.2.1",
"postcss-rem": "^1.1.5",
"postcss-simple-vars": "^5.0.2",
"postcss-sort-media-queries": "^1.7.26",
"postcss-url": "^8.0.0",
"rollup": "1.17.0",
"rollup-plugin-analyzer": "^3.3.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-css-only": "^2.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-postcss": "^3.1.8",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript": "^1.0.1",
"rollup-plugin-typescript2": "^0.28.0",
"rollup-plugin-uglify": "^6.0.4",
"rollup-plugin-vue": "^6.0.0-beta.8",
"sass-loader": "^10.0.3",
"style-resources-loader": "1.3.3",
"typescript": "~3.9.3"
,
"eslintConfig":
"root": true,
"env":
"node": true
,
"extends": [
"plugin:vue/essential",
"@vue/standard",
"@vue/typescript/recommended"
],
"parserOptions":
"ecmaVersion": 2020
,
"rules":
,
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
rollup.config.js
import vue from 'rollup-plugin-vue'
import node from '@rollup/plugin-node-resolve'
import cjs from '@rollup/plugin-commonjs'
import babel from '@rollup/plugin-babel'
import postcss from 'rollup-plugin-postcss'
import terser from 'rollup-plugin-terser'
import css from 'rollup-plugin-css-only'
import postcssImport from 'postcss-import'
import autoprefixer from 'autoprefixer'
import simplevars from 'postcss-simple-vars'
import nested from 'postcss-nested'
import postcssEach from 'postcss-each'
import postcssMixin from 'postcss-mixins'
import postcssColor from 'postcss-color-function'
import postcssCalc from 'postcss-calc'
import postcssextend from 'postcss-extend-rule'
import postcssDiscardComment from 'postcss-discard-comments'
import postcssDiscardEmpty from 'postcss-discard-empty'
import postcssUrl from 'postcss-url'
import postcssRem from 'postcss-rem'
import sortMedia from 'postcss-sort-media-queries'
import cssnano from 'cssnano'
import url from '@rollup/plugin-url'
import typescript from 'rollup-plugin-typescript2'
import analyze from 'rollup-plugin-analyzer'
import fs from 'fs'
import path from 'path'
const babelConfig =
exclude: 'node_modules/**',
babelHelpers: true,
babelrc: false,
presets: [['@babel/preset-env', modules: false ]]
const baseFolder = './src/'
const componentsFolder = 'components/'
const components = fs
.readdirSync(baseFolder + componentsFolder)
.filter((f) =>
fs.statSync(path.join(baseFolder + componentsFolder, f)).isDirectory()
)
const entries =
index: './src/index.ts',
...components.reduce((obj, name) =>
obj[name] = (baseFolder + componentsFolder + name)
return obj
, )
const capitalize = (s) =>
if (typeof s !== 'string') return ''
return s.charAt(0).toUpperCase() + s.slice(1)
const vuePluginConfig =
defaultLang:
style: 'postcss',
script: 'ts'
,
transformAssetUrls:
includeAbsolute: true
,
preProcessStyles: true,
compileTemplate: false,
template:
isProduction: true,
compilerOptions:
whitespace: 'condense'
,
style:
postcssPlugins: [
autoprefixer,
postcssImport(
resolve (id, basedir)
// resolve alias @css, @import '@css/style.css'
// because @css/ has 5 chars
if (id.startsWith('@css'))
// basedir will resolve to /src/components
return path.resolve('src/assets/styles/css', id.slice(5))
// resolve node_modules, @import '~normalize.css/normalize.css'
// similar to how css-loader's handling of node_modules
// if (id.startsWith('~'))
// return path.resolve(basedir, '../node_modules', id);
//
// resolve relative path, @import './components/style.css'
return path.resolve(basedir, id)
),
postcssEach,
postcssMixin,
simplevars,
postcssColor,
postcssCalc,
nested,
postcssextend,
postcssDiscardComment,
postcssDiscardEmpty,
postcssUrl( url: 'inline' ),
postcssRem(
baseline: 16, // Default to 16
// convert: 'px', // Default to rem
fallback: true, // Default to false
precision: 6 // Default to 5
),
sortMedia(
sort: 'mobile-first'
),
autoprefixer(
overrideBrowserslist: '> 1%, IE 6, Explorer >= 10, Safari >= 7'
),
cssnano(
zindex: false
)
]
export default () =>
const mapComponent = (name) =>
return [
input: baseFolder + componentsFolder + `$name/index.ts`,
external: ['vue'],
output:
format: 'umd',
name: capitalize(name),
file: `dist/components/$name/index.js`,
exports: 'named',
globals:
vue: 'Vue'
,
plugins: [
typescript(),
url(
include: [
'**/*.svg',
'**/*.png',
'**/*.gif',
'**/*.jpg',
'**/*.jpeg'
]
),
node(
extensions: ['.vue', '.js', '.ts']
),
cjs(),
vue(vuePluginConfig),
css(),
babel(babelConfig)
]
]
let config = [
input: entries,
external: ['vue'],
output:
format: 'esm',
dir: 'dist/esm'
,
plugins: [
typescript(),
cjs(),
url(
include: [
'**/*.svg',
'**/*.png',
'**/*.gif',
'**/*.jpg',
'**/*.jpeg'
]
),
node(
extensions: ['.vue', '.js', '.ts']
),
vue(vuePluginConfig),
css(),
babel(babelConfig),
analyze(),
terser(
output:
comments: '/^!/'
,
compress:
defaults: true
)
]
,
input: entries,
external: ['vue'],
output:
format: 'cjs',
dir: 'dist/cjs',
exports: 'named'
,
plugins: [
typescript(),
url(
include: [
'**/*.svg',
'**/*.png',
'**/*.gif',
'**/*.jpg',
'**/*.jpeg'
]
),
node(
extensions: ['.vue', '.js', '.ts']
),
vue(vuePluginConfig),
css(),
babel(babelConfig),
cjs()
]
,
//
// input: 'src/index.ts',
// external: ['vue'],
// output:
// format: 'umd',
// name: capitalize('vu'),
// file: 'dist/vueslib.js',
// exports: 'named',
// globals:
// vue: 'Vue'
//
// ,
// plugins: [
// typescript(),
// url(
// include: [
// '**/*.svg',
// '**/*.png',
// '**/*.gif',
// '**/*.jpg',
// '**/*.jpeg'
// ]
// ),
// node(
// extensions: ['.vue', '.js', '.ts']
// ),
// vue(vuePluginConfig),
// babel(babelConfig),
// cjs()
// ]
// ,
input: 'src/index.ts',
external: ['vue'],
output:
format: 'esm',
file: 'dist/vueslib.esm.js'
,
plugins: [
typescript(),
url(
include: [
'**/*.svg',
'**/*.png',
'**/*.gif',
'**/*.jpg',
'**/*.jpeg'
]
),
node(
extensions: ['.vue', '.js', '.ts', '.css']
),
vue(vuePluginConfig),
css(),
babel(babelConfig),
cjs()
]
,
// individual components
...components.map((f) => mapComponent(f)).reduce((r, a) => r.concat(a), [])
]
if (process.env.MINIFY === 'true')
config = config.filter((c) => !!c.output.file)
config.forEach((c) =>
c.output.file = c.output.file.replace(/\.js/g, '.min.js')
c.plugins.push(terser(
output:
comments: '/^!/'
,
compress:
defaults: true
))
)
return config
错误截图
组件
<template>
<!-- @css/_app-partials.css-->
<div>
<p class="yellow" @click="test()"> I am Dummy Component
<span class="reda">asdasdas</span>
</p>
<span class="red">asdasdas</span>
<img :src="require('../../assets/img/icons/download.jpeg')" />
<div class="imgtest">
</div>
</div>
</template>
<script lang="ts">
import defineComponent, PropType from 'vue'
export default defineComponent(
name: 'DummyComponent',
data ()
return
text1: 'I am Text Component'
,
props:
isValid:
type: Boolean,
default: false
,
msg:
type: Object as PropType<foo: string; bar: string>
,
methods:
test (): void
console.log('test1', this.$props.msg)
)
</script>
<style lang="postcss" scoped>
@import '../../assets/styles/css/_app-partials.css';
.yellow
color: red;
.reda
color: $black;
.red
color: green;
.imgtest
background-image: url('../../assets/img/icons/star-half.svg');
background-size: 100%;
width: 100px;
height: 100px;
</style>
github repository link https://github.com/shubhadip/vue-typescript-component-library
【问题讨论】:
这能回答你的问题吗? Rollup, Vue and Buble, unexpected token in scss file 【参考方案1】:看起来(在撰写本文时)汇总 vue plgin 不完全支持 vue3 和 scss。
github issue
急救
@P-Seebauer 的评论(上图)建议了解决此问题的方法。我添加了
rollup-plugin-scss
,这似乎取悦了汇总。构建继续进行。它同时处理 .scss 和 .css 文件。但是,由于预计 Vue.js 会处理这些问题,因此要求应用程序开发人员添加这样的插件似乎没有必要。
您还可以在以下位置查看@akauppi 的回答: Rollup, Vue and Buble, unexpected token in scss file(虽然这似乎是 vue2 特有的)
试试这个:
$ npm install --save-dev rollup-plugin-scss
在 rollup.config.js 中:
import scss from 'rollup-plugin-scss'; // handles '.css' and '.scss' plugins: ..., scss()
我真的不知道发生了什么,这里。以上对我有用(Vue.js 3(beta)和 rollup-plugin-vue 6.0.0-beta.6。
【讨论】:
实际上我通过将 lang="postcss" 更改为 lang="css" 来实现这一点。但现在范围不适用于嵌套类。它正在生成这样的类.tsetsfc3essfc3-sample[data-v-48e10e12]__test
【参考方案2】:
我通过将 lang="postcss" 更改为 lang="css" 然后调整 rollup-plugin-vue 选项来实现这个工作,这些选项在组件上内联 css 并在单独的文件中生成 css 必须使用 rollup-plugin-css-only
。工作代码在
Github
【讨论】:
以上是关于尝试使用 rollup 和 vueJs 3 构建 vue 组件库的主要内容,如果未能解决你的问题,请参考以下文章