Reputation: 173
I am trying to create a vue component library using rollup and vuejs. It worked with vue2 but was unable to parse css with vue3. I have upgraded the dependency in 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
}
Component
<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
Upvotes: 1
Views: 6786
Reputation: 173
I got this working by changing lang="postcss" to lang="css" and then tweaking rollup-plugin-vue options which inlined the css on the components and to generate css in separate file had to use rollup-plugin-css-only
.Working code is there in
Github
Upvotes: 1
Reputation: 35684
Looks like (at the time of writing) rollup vue plgin is not supporting vue3 and scss fully.
First aid
The way around this was suggested by @P-Seebauer's comment (above). I added
rollup-plugin-scss
to the mix, and it seems to please Rollup. The build proceeds. It handles both .scss and .css files.However, since Vue.js is expected to handle these, asking application developers to add such a plugin seems unnecessary.
You can also see @akauppi's answer at: Rollup, Vue and Buble, unexpected token in scss file (though that seems vue2 specific)
Try this:
$ npm install --save-dev rollup-plugin-scss
In rollup.config.js:
import scss from 'rollup-plugin-scss'; // handles '.css' and '.scss' plugins: { ..., scss() }
I don't really know what's going on, here. The above worked for me (Vue.js 3 (beta) and rollup-plugin-vue 6.0.0-beta.6.
Upvotes: 0