问题描述
我正在尝试使用汇总和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,output: {
format: 'esm',dir: 'dist/esm'
},plugins: [
typescript(),url({
include: [
'**/*.svg','**/*.jpeg'
]
}),node({
extensions: ['.vue','.ts']
}),babel(babelConfig),analyze(),terser({
output: {
comments: '/^!/'
},compress: {
defaults: true
}
})
]
},{
input: entries,output: {
format: 'cjs',dir: 'dist/cjs',exports: 'named'
},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','.ts']
// }),// vue(vuePluginConfig),// babel(babelConfig),// cjs()
// ]
// },{
input: 'src/index.ts',file: 'dist/vueslib.esm.js'
},'.ts','.css']
}),// 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
解决方法
看起来(在撰写本文时)汇总vue plgin不完全支持vue3和scss。
急救
@ 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”,然后调整rollup-plugin-vue选项(使其内联组件上的CSS并在单独的文件中生成CSS)来进行工作,必须使用{{1 }。工作代码在其中 Github