簡體   English   中英

從 javascript package 的子文件夾導入

[英]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/xxxmaterial-ui/yyy相同的結構。

人們建議使用別名或命名導出,但我無法使其工作。

最接近我的問題的是以下問題:

從 npm package 的子文件夾導入

我想實現同樣的事情,但使用typescriptrollup

我想我錯過了一些東西,謝謝。

首先,兩者之間的唯一區別

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";

模塊解析器將執行此操作(大大簡化,因為完整的算法在這里無關緊要):

  • Go 到node_modules
  • 查找my-project
  • 加載package.json
  • 返回mainmodule中的文件

這會起作用,因為我們有

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

在后一種情況下,它將再次查看mainmodule

但我們有:

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是策划的。

經過多次試驗和錯誤后,我能夠通過傳入輸入列表、使用preserveModulespreserveModulesRoot選項以及簡單的安裝后腳本來完成這項工作。

這是我的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM