[英]Importing from subfolders for a javascript package
我有一個 typescript 庫由多個文件夾組成。 每個文件夾都包含一個 index.ts 文件,該文件導出一些業務邏輯。 我正在嘗試將此與匯總捆綁在一起以在呼叫站點上實現此行為:
import { Button, ButtonProps } from 'my-lib/button'
import { Input, Textarea } from 'my-lib/input'
import { Row, Column } from 'my-lib/grid'
這是目錄結構:
我在src/
下有一個主index.ts
,其中包含:
export * from './button';
export * from './input';
export * from './grid';
使用這種風格,我可以做到:
import { Button, Input, InputProps, Row, Column } from 'my-lib'
但我不想要這個。 我想通過它們的命名空間訪問每個模塊。 如果我從index.ts
文件中刪除導出,我所能做的就是:
import { Button } from 'my-lib/dist/button'
這是我以前沒有看到的。 將dist/
添加到 import 語句意味着我正在通過相對路徑訪問模塊。 我想要my-lib/Button
。
我正在使用匯總。 我嘗試使用alias
插件但沒有用。 以下是我的匯總配置:
const customResolver = resolve({
extensions: ['ts'],
});
export default {
input: `src/index.ts`,
output: [
{
file: pkg.main,
format: 'cjs',
sourcemap: true,
// plugins: [terser()],
},
{
file: pkg.module,
format: 'es',
sourcemap: true,
plugins: [terser()],
},
],
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
external: [],
watch: {
include: 'src/**',
},
plugins: [
// Allow json resolution
json(),
// Compile TypeScript files
typescript({ useTsconfigDeclarationDir: true }),
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
commonjs(),
// Allow node_modules resolution, so you can use 'external' to control
// which external modules to include in the bundle
// https://github.com/rollup/rollup-plugin-node-resolve#usage
resolve(),
// Resolve source maps to the original source
sourceMaps(),
alias({
entries: [
{ find: 'my-lib/button', replacement: './dist/button' },
{ find: 'my-lib/input', replacement: './dist/input' },
{ find: 'my-lib/grid', replacement: './dist/grid' },
],
customResolver,
}),
],
};
這是tsconfig
文件:
{
"compilerOptions": {
"target": "es5",
"module": "ES6",
"lib": ["ES2017", "ES7", "ES6", "DOM"],
"declaration": true,
"declarationDir": "dist",
"outDir": "dist",
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"allowJs": false,
"moduleResolution": "node",
"resolveJsonModule": true,
"baseUrl": "./src",
"paths": {
"my-lib/button": ["./src/button"],
"my-lib/input": ["./src/input"],
"my-lib/grid": ["./src/grid"]
}
},
"exclude": ["node_modules", "dist", "**/*.test.ts"],
"include": ["src/**/*.ts"]
}
我不知道如何通過 rollup 實現與lodash/xxx
或material-ui/yyy
相同的結構。
人們建議使用別名或命名導出,但我無法使其工作。
最接近我的問題的是以下問題:
我想實現同樣的事情,但使用typescript
和rollup
。
我想我錯過了一些東西,謝謝。
首先,兩者之間的唯一區別
import { Button } from 'my-lib/dist/button'
和
import { Button } from 'my-lib/button'
只是一個目錄級別。
曾經說過,直到你有"outDir": "dist",
在你的tsconfig.json
文件中,你需要將dist/
添加到你的import
語句中。
確實,您作為示例的兩個庫都與根目錄中的文件一起分發: lodash直接在根目錄中有js
文件,而material-ui在其tsconfig.json
文件中沒有outDir
選項(這意味着將Z78E62261F6389F1CED668文件寫入根目錄) .
希望這可以幫助。
這是可能的,但需要一些額外的步驟。 上面提到過,這是Material-UI采用的方法。
訣竅是發布一個精選的dist
文件夾,而不是你的 repo 的根文件夾。
首先,讓我們明確一點,您的庫是使用 CommonJS 還是 ESM 構建的並不重要。 這是關於模塊分辨率的。
假設該項目名為my-package
。
現在大多數項目,在我們將src/
構建到dist/
之后,
my-package
package.json
src/
index.js
dist/
index.js
並在 package.json
"main": "dist/index.js"
或對於 esm
"module": "dist/index.js"
大多數項目只是添加.npmignore
並發布項目的根目錄,因此在安裝時,項目最終會出現在node_modules
中,如下所示:
node_modules
my-package/
package.json
dist/
index.js
安裝后,考慮這個導入:
import myProject from "my-project";
模塊解析器將執行此操作(大大簡化,因為完整的算法在這里無關緊要):
node_modules
my-project
package.json
main
或module
中的文件這會起作用,因為我們有
node_modules
my-package/
package.json
dist/
index.js
import something from "my-project/something";
分辨率算法將與
node_modules
my-project/
somthing.js
也與
node_modules
my-project/
something/
index.js
與
node_modules
my-project/
something/
package.json
在后一種情況下,它將再次查看main
或module
。
但我們有:
node_modules
my-package/
package.json
dist/
index.js
訣竅是,不要使用dist
文件夾發布項目根目錄,而是“坦白” dist
文件夾並使用npm publish dist
dist
夾來發布 dist 文件夾。
坦率地說(如坦率的一封信),您需要在dist
文件夾中創建一個package.json
; 添加README.md
LICENSE
等。
可以在此處找到如何完成此操作的一個相當簡短的示例。
因此,鑒於我們在構建之后:
node_modules
my-package/
package.json
dist/
index.js
something.js
一旦發布,我們得到
node_modules
my-project/
package.json
index.js
something.js
其中package.json
是策划的。
經過多次試驗和錯誤后,我能夠通過傳入輸入列表、使用preserveModules和preserveModulesRoot選項以及簡單的安裝后腳本來完成這項工作。
這是我的rollup.config.js
const options = {
input: [
'src/index.ts',
'src/api/index.ts',
'src/components/index.ts',
'src/contexts/index.ts',
'src/hooks/index.ts',
'src/lib/index.ts',
'src/types/index.ts',
'src/utils/index.ts',
'src/UI/index.ts',
],
output: [
{
format: 'cjs',
dir: 'dist',
exports: 'auto',
preserveModules: true,
preserveModulesRoot: 'src',
sourcemap: true,
},
],
plugins: [
// Preferably set as first plugin.
peerDepsExternal(),
typescript({
tsconfig: './tsconfig.rollup.json',
}),
postcss({
extract: false,
modules: true,
use: ['sass'],
}),
],
};
export default options;
腳本/postinstall.sh
#!/usr/bin/env bash
set -e;
# skip postinstall if npm install for development
# rollup.config.js is not included in dist
if [ -f "rollup.config.js" ]; then
echo "skipping your package's postinstall routine.";
exit 0;
fi
echo 'Copying files from dist folder into root project folder...'
cp -r dist/* ./ && rm -rf dist
echo 'Postinstall done!'
package.json
"scripts": {
"postinstall": "./scripts/postinstall.sh",
},
這會將 output 所有文件編譯到dist文件夾。 postinstall 腳本會將所有文件從dist復制到根項目文件夾中。
注意*:在本地運行 npm 安裝時應跳過安裝后腳本。 這是通過檢查rollup.config.js是否存在來完成的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.