我正在创建一个库,它导出大量 React 组件以及一些用于我公司内多个项目的打字稿实用程序,但是除了从库的根导出所有内容之外,我似乎无法做任何其他事情。
我有以下文件夹结构,.tsx和utils.ts仅导出命名属性,根index.ts包含
export * from './Button';
等...
那么 src/index.ts
就是 export * from './ui'
等等......
src/
ui/
Button/
Button.tsx
Input/
Input.tsx
index.ts
utils/
myUtilFunc1.ts
myUtilFunc2.ts
index.ts
使用下面的 webpack 配置
const path = require("path");
module.exports = {
entry: "./src/index.ts",
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
library: "@company/library",
libraryTarget: "umd",
umdNamedDefine: true,
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/,
},
],
},
externals: {
react: "react",
"react-dom": "react-dom",
},
};
以及以下 package.json 属性
"main": "dist/main.js",
"module": "dist/main.js",
"types": "dist/types/index.d.ts",
当我在另一个项目中使用这个库时,我可以根据需要导入,如下所示
import { Button, myUtilFunc2 } from "@company/library"
但我想像这样导入
import { Button } from "@company/library/ui"
和 import {myUtilFunc2 } from "@company/library/util"
我知道这应该是可能的,因为 mui 和其他库都有这个。我正在使用 webpack,因为我尝试了这将汇总,甚至使用 lerna 设置了一个 mono 存储库(效果很好,但我只是觉得我不需要为此构建 2 个 npm 包,它们都可以包含在一个包中)
您可以使用 webpack alias
进行存档配置您的 webpack 以将 @company 别名解析为组件所在的适当路径。这可以通过将以下内容添加到您的 webpack 配置中来完成:
const path = require('path');
module.exports = {
// ...
resolve: {
alias: {
'@company': path.resolve(__dirname, 'path/to/company/library/ui'),
},
},
// ...
};
但您需要确保遵循相同的结构:
- company
- library
- ui
- Button.js (Button comp)
那么这应该有效:
import React from 'react';
import { Button } from '@company/library/ui';
实现目标的一种可能方法是使用
package.json
文件中的导出字段,该字段允许您在使用 import "package"
或 import "package/sub/path"
等模块请求时声明应使用哪个模块。 webpack 5 及更新版本支持此功能。
例如,您的
package.json
中可以有类似的内容:
{
"name": "@company/library",
"main": "dist/main.js",
"module": "dist/main.js",
"types": "dist/types/index.d.ts",
"exports": {
".": "./dist/main.js",
"./ui": "./dist/ui/index.js",
"./utils": "./dist/utils/index.js"
}
}
这样,您就可以像这样导入子模块:
import { Button } from "@company/library/ui";
import { myUtilFunc2 } from "@company/library/utils";
根据webpack文档:
当指定exports字段时,只有这些模块请求 可用的。任何其他请求都会导致 ModuleNotFound 错误。
因此,如果您有太多项目模块,这可能会很乏味或不切实际。
在这种情况下,您可以尝试使用一些允许您指定多个或动态模块请求的语法功能,例如:
要了解更多信息,请参阅 Webpack 5 通用语法、替代方案。
但它有一些兼容性问题。
您可以从此资源了解有关导出字段及其语法的更多信息。
为了在从库中导入组件和实用程序时获得所需的文件夹结构,您需要对项目的配置和文件结构进行一些调整。您可以使用 Webpack 配置中的resolve.alias 属性为特定目录创建别名,以便可以直接导入它们。
以下是如何修改 Webpack 配置以实现所需的导入语法:
更新您的 Webpack 配置:
const path = require("path");
module.exports = {
entry: "./src/index.ts",
resolve: {
extensions: [".ts", ".tsx", ".js"],
alias: {
"@company/library": path.resolve(__dirname, "src"),
},
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
library: "@company/library",
libraryTarget: "umd",
umdNamedDefine: true,
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/,
},
],
},
externals: {
react: "react",
"react-dom": "react-dom",
},
};
修改从 src/index.ts 导出的方式:
// src/index.ts
export * from "./ui";
export * from "./utils";
更新您的文件结构:
src/
ui/
Button/
Button.tsx
index.ts // Add index.ts to re-export Button.tsx
Input/
Input.tsx
index.ts // Add index.ts to re-export Input.tsx
index.ts // Add index.ts to re-export components
utils/
myUtilFunc1.ts
myUtilFunc2.ts
index.ts // Add index.ts to re-export utilities
index.ts // Re-export from ui and utils
通过这些更改,您应该能够根据需要导入组件和实用程序:
// Importing components
import { Button } from "@company/library/ui";
import { Input } from "@company/library/ui";
// Importing utilities
import { myUtilFunc1, myUtilFunc2 } from "@company/library/utils";
这将为您提供所需的文件夹结构,同时将所有内容保留在单个 npm 包中。 Webpack 配置中的别名允许您使用 @company/library 导入路径,该路径指向库的根 src 目录。每个目录中的index.ts 文件用于重新导出组件和实用程序,使它们可以从各自的文件夹轻松访问。