为了账号安全,请及时绑定邮箱和手机立即绑定

从 javascript 包的子文件夹导入

从 javascript 包的子文件夹导入

慕虎7371278 2022-10-13 15:53:24
我有一个打字稿库,由多个文件夹组成。每个文件夹都包含一个 index.ts 文件,该文件导出一些业务逻辑。我正在尝试将此与汇总捆绑在一起以在呼叫站点上实现此行为:import { Button, ButtonProps } from 'my-lib/button'import { Input, Textarea } from 'my-lib/input'import { Row, Column } from 'my-lib/grid'这是目录结构:我有一个主要内容index.ts,src/其中包含: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/到导入语句意味着我正在通过相对路径访问模块。我想要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,    }),  ],};
查看完整描述

3 回答

?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

这是可能的,但需要一些额外的步骤。上面提到过,这是 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

  • 返回文件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

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

但我们有:

node_modules
  my-package/
    package.json
    dist/
      index.js

诀窍

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

Frank(如frank a letter)表示您需要package.jsondist文件夹中创建一个;添加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策划的在哪里。


查看完整回答
反对 回复 2022-10-13
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

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

import { Button } from 'my-lib/dist/button'

import { Button } from 'my-lib/button'

只是一个目录级别。

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

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

希望这可以帮助。


查看完整回答
反对 回复 2022-10-13
?
当年话下

TA贡献1890条经验 获得超9个赞

经过多次试验和错误后,我能够通过传入输入列表、使用 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!'

包.json


"scripts": {

    "postinstall": "./scripts/postinstall.sh",

  },

这将编译所有文件并将其输出到dist文件夹。postinstall 脚本会将所有文件从dist复制到根项目文件夹中。


注意*:在本地运行 npm install 时应跳过安装后脚本。这是通过检查rollup.config.js是否存在来完成的。


查看完整回答
反对 回复 2022-10-13
  • 3 回答
  • 0 关注
  • 208 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号