如何使用CSS样式的代码拆分构建UI组件库

2guxujil  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(170)

我想创建一个UI组件库,其中消费者只能绑定他们实际使用的组件的样式。
假设这个问题与框架无关,因为我更感兴趣的是评估现有的方法。
这个想法是让用户能够

import { Button } from '@mylib/ui`

并且不需要转到他们的main.ts并添加

import '@mylib/ui/styles/main.min.css`

现在,很明显,第一个解决方案是避免将CSS捆绑在一起,这样用户就能够为每个组件导入单独的样式表

import '@mylib/ui/styles/button.min.css';
import '@mylib/ui/styles/accordion.min.css';

现在,如果您使用少量组件并希望控制捆绑包的大小,这种方法可以很好地工作,但如果消费者开始使用十几个组件,它就无法扩展。
我该如何克服这一挑战?
我能想到的唯一方法是内联样式,但由于缺少选择器、媒体查询等,这种方法不起作用。

我希望实现的是一种方法,让消费者声明他们需要什么,并获得该组件的样式,而无需任何额外的配置/导入,同时保留仅绑定属于导入组件的CSS的能力

import { Button } from '@mylib/ui`

我正在挠头想出一个办法来解决这个问题。

dsekswqp

dsekswqp1#

我认为如果不考虑你所使用的框架很难回答这个问题。如果我们不知道框架,为每个组件导入CSS表单可能是这个问题最直接的答案。
了解库的设计框架是非常重要的,因为这样你就知道有什么捆绑工具和技术可用。最近我不得不解决Vue 3 SFC库的这样一个问题。我找到的解决方案是提供非捆绑的库代码,(只翻译.vue文件)(你可以检查unbuild tool)。
我相信其他框架也可以提供类似的解决方案,当然,这样的库也有缺点(例如,没有捆绑器就不能使用它)。
然而,这个解决方案直接回答了您的问题,因为使用这样的构造库,您可以编写如下代码:

import { Button } from '@mylib/ui`

和bundler将仅从该组件捆绑样式(因为在SFC文件中样式位于文件内部)。
PS,如果你想玩这个解决方案,记得在library package.json中设置sideEffects: false,这样使用你的库的项目中的捆绑程序就会知道它可以对你的库进行树抖动。

2vuwiymt

2vuwiymt2#

感谢@Maksymilian Tomczyk和他使用unbuild的建议,我已经找到了满足我需要的配置:

// vite.config.ts
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
  /**
   * Build is handled by Unbuild
   */
});
// build.config.ts
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
  entries: [
    { builder: "mkdist", input: "./src/" },
    { builder: "mkdist", input: "./src/", format: "cjs", ext: "js" },
  ],
  declaration: true,
  clean: true,
});
{
"name": "my-lib",
  "version": "0.0.4",
  "private": false,
  "files": [
    "dist"
  ],
  "module": "./dist/index.mjs",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.js"
    }
  },
  "sideEffects":false,
  "scripts": {
    "build: "unbuild"
  }
}

以下是项目的结构:

以下是最终输出:

这创建了一个未受影响的输出,消费者可以导入并使用他们的捆绑器来优化树摇动/编译。
unbundled仅预编译TypeScript和SASS

相关问题