Vue Typescript 组件库 - 使用 Webpack 和 SASS

Posted

技术标签:

【中文标题】Vue Typescript 组件库 - 使用 Webpack 和 SASS【英文标题】:Vue Typescript component library - Working with Webpack and SASS 【发布时间】:2020-10-17 00:45:06 【问题描述】:

我目前正在为一家公司构建 Vue UI 组件库,在此过程中,我使用 webpack 作为默认捆绑器。我想将整个项目构建成一个 npm 包,然后可以通过私有 git 包存储库进行分发。 软件包分发已启动并正在运行,但我似乎无法以正确的方式导出组件,因此可以在另一个项目中使用。

使用的不同工具的版本:

npm:6.14.4

节点:12.17.0

纱线:1.22.0

@vue/cli: 4.4.1

tsc:3.9.5

项目结构如下:

public
src
 - assets
  | - css
  |  | - tailwind.css
  | - fonts
  |  | - stylesheet.css
 - component
  | - LbButton
  |  | - LbButton.vue
  |  | - index.ts
  | - Lbtag
  |  | - LbTag.vue
  |  | - index.ts
  | - ...
 - theme
  | - index.ts
  | - Theme.ts
 - typedefs
  | - types.ts
  | - events.ts
  | - model.ts
  | - states.ts
 - views
  | - Home.vue
 - App.vue
 - index.ts
 - main.ts
 - plugin.ts
 - shims-vue.d.ts
vue.config.js
tailwind.config.js
tsconfig.json
postcss.config.js
babel.config.js
package.json

当前设置包含以下配置:

package.json

... "main": "./dist/@livebackend/ui.common.js", ... “脚本”: "serve": "vue-cli-service serve", "build": "vue-cli-service build --target lib --name @livebackend/ui src/index.ts", “测试:单元”:“vue-cli 服务测试:单元” , “文件”:[ "dist/*", "src/*", “民众/*”, "*.json", "*.vue", "*.ts", “*.js” ], “依赖”: "@kazupon/vue-i18n-loader": "^0.5.0", "@types/lodash": "^4.14.152", "@types/vue-i18n": "^7.0.0", "@types/vue-select": "^2.5.0", "core-js": "^3.6.4", “日期-fns”:“^2.14.0”, "lodash": "^4.17.15", "v-日历": "^1.0.6", "vue": "^2.6.11", "vue-class-component": "^7.2.3", “vue-i18n”:“^8.18.1”, "vue-infinite-loading": "^2.4.5", "vue-property-decorator": "^8.4.1", "vue-select": "^3.10.3", "vuex": "^3.1.3", “vuex 类”:“^0.3.2” , “对等依赖”: "@vue/composition-api": "^0.6.7" , “开发依赖”: "@types/chai": "^4.2.11", "@types/mocha": "^5.2.4", "@vue/cli-plugin-babel": "~4.3.0", "@vue/cli-plugin-typescript": "~4.3.0", "@vue/cli-plugin-unit-mocha": "~4.3.0", "@vue/cli-plugin-vuex": "~4.3.0", "@vue/cli-service": "~4.3.0", "@vue/composition-api": "^0.6.7", "@vue/test-utils": "1.0.0-beta.31", "柴": "^4.1.2", “节点萨斯”:“^4.14.1”, “萨斯”:“^1.26.5”, "sass-loader": "^8.0.2", "样式加载器": "^1.2.1", “tailwindcss”:“1.4.6”, "ts-loader": "^7.0.5", “打字稿”:“〜3.9.5”, "vue-style-loader": "^4.1.2", “vue 模板编译器”:“^2.6.11” , “版本”:“0.4.8”

tsconfig


  "compilerOptions": 
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "declaration": true,
    "importHelpers": true,
    "moduleResolution": "node",
    "noImplicitAny": false,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": 
      "@/*": [
        "src/*"
      ]
    ,
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  ,
  "include": [
    "src/**/*.ts",
    "src/**/*.vue"
  ],
  "files": [
    "src/vue-shims.d.ts"
  ],
  "exclude": [
    "node_modules"
  ]

vue.config.js

module.exports = 
  publicPath: "./src",
  devServer: 
    proxy: "http://localhost:3000"
  ,
  chainWebpack: config => 
    config.plugins.delete("optimize-css");
  ,
  configureWebpack: 
    module: 
      rules: [
        
          resourceQuery: /blockType=i18n/,
          type: "javascript/auto",
          loader: "@kazupon/vue-i18n-loader"
        
      ]
    
  
;

tailwind.config.js

const settings = 
  theme: ,
  variants: ,
  plugins: []
;

if (process.env.NODE_ENV === "production") 
  settings.purge = ["./src/**/*.html", "./src/**/*.vue", "./src/**/*.jsx"];


module.exports = settings;

src/index.ts

export  default as Theme  from "./theme";
export  default as LbButton  from "./components/lbButton";
export  default as LbInputField  from "./components/lbInputField";
export  default as LbIconButton  from "./components/lbIconButton";
export  default as LbTag  from "./components/lbTag";
export  default as LbCard  from "./components/lbCard";
export  default as LbFB  from "./components/lbFB";
export  default as LbDatePicker  from "./components/lbDatePicker";
export  default as LbRadio  from "./components/lbRadio";
export  default as LbLoading  from "./components/lbLoading";
export  default as LbSlider  from "./components/lbSlider";
export  default as LbSwitch  from "./components/lbSwitch";
export  default as LbTable  from "./components/lbTable";
import plugin from "./plugin";
export default plugin; 

ma​​in.ts

import Vue from "vue";
import VueI18n from "vue-i18n";
import vSelect from "vue-select";
import VCalendar from "v-calendar";
import "@/assets/css/tailwind.css";
import "@/assets/fonts/stylesheet.css";
import "vue-select/dist/vue-select.css";
import InfiniteLoading from "vue-infinite-loading";

import App from "./App.vue";
import messages from "./tranlations";

Vue.config.productionTip = false;

Vue.component("v-select", vSelect);
Vue.use(VCalendar, 
  componentPrefix: "v" 
);
Vue.use(VueI18n);
Vue.use(InfiniteLoading);

const i18n = new VueI18n(
  locale: "en",
  messages
);

new Vue(
  i18n,
  render: h => h(App)
).$mount("#app");

如果我需要发布更多文件,请随时询问。 当我将所有这些捆绑在一起并将其包含在像 import LbButton from "@livebackend/ui" 这样的项目中时,我收到一个错误,告诉我 vue 找不到类型声明或模块。然后当我尝试从"@livebackend/ui/src" 导入它时,我收到另一个错误,告诉我 vue 无法弄清楚“@”是什么意思。我使用“@”来查找项目中的相关模块。

有没有人遇到过这些问题?

【问题讨论】:

【参考方案1】:

我也在搜索相同的信息并发现了这个问题,我尝试了许多 repos 和博客/教程,https://github.com/team-innovation/vue-sfc-rollup 是我迄今为止找到的最佳解决方案,但一旦我将使用它,我会更新这个答案更长。我昨天才开始,我正在将功能一个一个放在那里,看看我是否击中了什么。

编辑:2020 年 11 月 2 日

我不得不放

configureWebpack: 
  resolve: 
      alias: 
        vue: path.resolve("./node_modules/vue")
      
    

修复问题[Vue warn]: $listeners is read-only.

参考:https://github.com/team-innovation/vue-sfc-rollup/issues/26

【讨论】:

以上是关于Vue Typescript 组件库 - 使用 Webpack 和 SASS的主要内容,如果未能解决你的问题,请参考以下文章

使用 Vite、Vue 3 和 Typescript 将组件库发布到 npm

Vue Typescript 组件库 - 使用 Webpack 和 SASS

使用Vite和TypeScript带你从零打造一个属于自己的Vue3组件库

vue组件库用@vue/cli构建typescript版UI库 -安装常用npm包配置脚本

使用Typescript和类组件装饰器时如何将数组传递给Vue中的props

React Hooks Typescript 开发的一款 H5 移动端 组件库