当前位置: 首页 > 知识库问答 >
问题:

尝试使用rollup和vueJs 3构建vue组件库

轩辕实
2023-03-14

我正在尝试使用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存储库链接https://github.com/shubhadip/vue-typescript-component-library

共有2个答案

米子轩
2023-03-14

看起来(在撰写本文时)rollup vue plgin不完全支持vue3和scss。

github问题

@P-Seebauer的评论(上图)提出了解决方法。我在混搭中添加了rollup插件scss,似乎很喜欢rollup。建造继续进行。它可以同时处理这两个问题。scss和。css文件。

然而,自从Vue。js有望处理这些问题,要求应用程序开发人员添加这样的插件似乎是不必要的。

您还可以在以下位置看到@akauppi的答案:Rollup、Vue和Buble,scss文件中的意外标记(尽管这似乎与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版)和汇总插件Vue 6.0.0-beta版)。6.

姬康平
2023-03-14

我通过将lang="postcss"更改为lang="css",然后调整rollup-plugin-vue选项来在组件上内联css并在单独的文件中生成css必须使用rollup-plugin-css-only。工作代码在Github中

 类似资料:
  • 我一直在遵循“Django by example”的教程,该教程介绍了Solr和Haystack,但遇到了一个问题。我已在settings.py中对已安装的_应用程序进行了必要的更改,并添加了以下内容: 然后我就跑 我得到这个错误 这是我的search_index.py文件 当我运行django shell时,我可以很好地导入haystack,但当我运行以下命令时: 进入第二行后,我得到了完全相同

  • 本文向大家介绍使用 Vue cli 3.0 构建自定义组件库的方法,包括了使用 Vue cli 3.0 构建自定义组件库的方法的使用技巧和注意事项,需要的朋友参考一下 本文旨在给大家提供一种构建一个完整 UI 库脚手架的思路:包括如何快速并优雅地构建UI库的主页、如何托管主页、如何编写脚本提升自己的开发效率、如何生成 CHANGELOG 等 前言 主流的开源 UI 库代码结构主要分为三大部分: 组

  • 我目前正在为一家公司构建一个Vue UI组件库,在这个过程中,我使用webpack作为默认绑定程序。我想把整个项目构建成一个npm包,然后可以通过一个私有的git包存储库分发。包分发已经启动并运行,但我似乎无法以正确的方式导出组件,以便在另一个项目中使用。 使用的不同工具的版本: 国家预防机制:6.14.4 节点:12.17.0 纱线:1.22.0 @VUE/CLI:4.4.1 TSC:3.9.5

  • DEPRECATED We are deprecating this template in favor of the webpack one. Some things may have changed and I haven't tested this template in a while. Check the Groceries Vue app for an example of a wor

  • 使用汇总打包Vue组件时,会出现此错误: 卷起来。配置。js: 按钮vue: 有解决办法吗? 所以我找到了一个更好的方法: 最好使用vue sfc汇总来打包vue组件。

  • 我正在尝试构建复杂的JSON对象嵌套数组。我正在努力使用JOLT获得我期望的结构。任何帮助都将不胜感激。 我正试图从appspot上理解JOLT,但对于我来说,很难理解对数据集进行递归迭代。 即使数组中有 1000 个对象,“JobId”也应该与毫秒相同,这就是为什么我一次生成“JobId”而不是在每个对象中并尝试在下一次迭代中移动到正确的位置失败的原因。 输入的 JSON 为: 到目前为止,我想