从子文件夹导入 javascript 包

ali*_*lix 8 javascript rollup typescript

我有一个由多个文件夹组成的打字稿库。每个文件夹都包含一个 index.ts 文件,该文件导出一些业务逻辑。我正在尝试将其与 rollup 捆绑在一起以在调用站点上实现此行为:

import { Button, ButtonProps } from 'my-lib/button'
import { Input, Textarea } from 'my-lib/input'
import { Row, Column } from 'my-lib/grid'
Run Code Online (Sandbox Code Playgroud)

这是目录结构:

在此处输入图片说明

我有一个主要内容index.tssrc/其中包含:

export * from './button';
export * from './input';
export * from './grid';
Run Code Online (Sandbox Code Playgroud)

有了这种风格,我可以做到:

import { Button, Input, InputProps, Row, Column } from 'my-lib'
Run Code Online (Sandbox Code Playgroud)

但我不想要这个。我想通过它们的命名空间访问每个模块。如果我从index.ts文件中删除导出,我所能做的就是:

import { Button } from 'my-lib/dist/button'
Run Code Online (Sandbox Code Playgroud)

这是我以前没有看到的。添加dist/到导入语句意味着我通过相对路径访问模块。我要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,
    }),
  ],
};

Run Code Online (Sandbox Code Playgroud)

这是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"]
}
Run Code Online (Sandbox Code Playgroud)

我不知道该如何实现相同的结构,lodash/xxxmaterial-ui/yyy与汇总。

人们建议使用别名或命名导出,但我无法使其工作。

最接近我的问题的是以下问题:

从 npm 包的子文件夹导入

我想达到同样的目的,但使用typescriptrollup

我想我错过了一些东西,谢谢。

Dan*_*cci 5

首先,两者之间的唯一区别

import { Button } from 'my-lib/dist/button'
Run Code Online (Sandbox Code Playgroud)

import { Button } from 'my-lib/button'
Run Code Online (Sandbox Code Playgroud)

只是又一个目录级别。

曾经说过,"outDir": "dist",在您的tsconfig.json文件中有您需要添加dist/到您的import语句之前。

确实,你举的两个库都是在根目录下分发文件的:lodash直接在根目录下有js文件,而material-uioutDir在其tsconfig.json文件中没有option (即写输出文件到根目录)。

希望这可以帮助。


Izh*_*aki 5

这是可能的,但需要一些额外的步骤。上面提到了,这是 Material-UI 采取的方法。

诀窍是发布一个策划dist文件夹,而不是你的回购的根文件夹。

建筑

首先,让我们明确一点,您的库是使用 CommonJS 还是 ESM 构建的并不重要。这是关于模块分辨率

假设项目名为my-package.

现在大多数项目,在我们建成src/dist/都会有

my-package
  package.json
  src/
    index.js
  dist/
    index.js
Run Code Online (Sandbox Code Playgroud)

并在 package.json 中

"main": "dist/index.js"
Run Code Online (Sandbox Code Playgroud)

或为 esm

"module": "dist/index.js"
Run Code Online (Sandbox Code Playgroud)

出版

大多数项目只是添加.npmignore和发布项目的根目录,因此安装后项目最终会node_modules像这样:

node_modules
  my-package/
    package.json
    dist/
      index.js
Run Code Online (Sandbox Code Playgroud)

解决

安装后,请考虑此导入:

import myProject from "my-project";
Run Code Online (Sandbox Code Playgroud)

模块解析器将执行此操作(大大简化,因为这里的完整算法无关紧要):

  • node_modules
  • my-project
  • 加载 package.json
  • 将文件返回mainmodule

哪个会起作用,因为我们有

node_modules
  my-package/
    package.json
    dist/
      index.js
Run Code Online (Sandbox Code Playgroud)

解析子路径

import something from "my-project/something";
Run Code Online (Sandbox Code Playgroud)

分辨率算法将与

node_modules
  my-project/
    somthing.js
Run Code Online (Sandbox Code Playgroud)

还有

node_modules
  my-project/
    something/
      index.js
Run Code Online (Sandbox Code Playgroud)

node_modules
  my-project/
    something/
      package.json
Run Code Online (Sandbox Code Playgroud)

在后一种情况下,它将再次查看mainor module

但我们有:

node_modules
  my-package/
    package.json
    dist/
      index.js
Run Code Online (Sandbox Code Playgroud)

伎俩

诀窍是,不要使用其dist文件夹发布项目根目录,而是“坦白”dist文件夹并dist使用npm publish dist代替发布文件夹。

通过坦率(如坦率的信),您需要package.jsondist文件夹中创建一个;添加README.md LICENSE

可以在此处找到有关如何完成此操作的相当简短的示例。

所以,考虑到我们在构建之后:

node_modules
  my-package/
    package.json
    dist/
      index.js
      something.js
Run Code Online (Sandbox Code Playgroud)

一旦发布,我们得到

node_modules
  my-project/
    package.json
    index.js
    something.js
Run Code Online (Sandbox Code Playgroud)

package.json策展人在哪里。