从 npm 包的子文件夹导入 [英] Import from subfolder of npm package

查看:36
本文介绍了从 npm 包的子文件夹导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直致力于创建一个小型 React 组件库,以用于其他几个项目.我在内部发布包(使用私有 GitHub 存储库),然后包含在另一个项目中.但是,当我从包的子目录导入时,我无法这样做,因为路径不匹配.

I've been working on creating a small library of React components for use in several other projects. I am publishing the package internally (using a private GitHub repository) and then including in another project. However, when I go to import from a subdirectory of the package I am not able to do so as the paths don't match.

使用该包的项目都使用 webpack 来捆绑/转译代码,因为我尽量避免在组件库中进行任何构建.

The projects using the package all utilize webpack to bundle/transpile code as I am trying to avoid doing any building in the component library if possible.

- package.json
- src/
  - index.js
  - Button/
    - index.js
    - Button.jsx
    - ButtonGroup.jsx
  - Header/
    - index.js
    - Header.jsx (default export)

package.json

...
"main": "./src/index.js",
"scripts": "",
...

src/Button/index.js

import Button from './Button';
import ButtonGroup from './ButtonGroup';

export default Button;

export { Button, ButtonGroup};

src/index.js

如果只从子目录导入,这个文件真的有必要吗?

Is this file actually necessary if only importing from subdirectories?

import Button from './Button';
import ButtonGroup from './Button/ButtonGroup';
import Header from './Header';

export { Button, ButtonGroup, Header };

其他项目

// This project is responsible for building/transpiling after importing
import { Button, ButtonGroup } from 'components-library/Button';

示例

Material-UI 是一个 React 组件库,通过以下方式使用 require: import { RadioButtonGroup } from 'material-ui/RadioButton.我试图弄清楚这对他们来说是如何工作的,但还没有成功.

Example

Material-UI is a library of React components that is used by requiring in the following fashion: import { RadioButtonGroup } from 'material-ui/RadioButton. I've tried to figure out how this works for them but to no avail yet.

  • 我会如何使用 webpack 在 npm 包子文件夹中导入模块?
    • 这几乎是我需要的正确方法,除了那里使用的导入路径涉及 src/ 目录,我试图避免(应该是 component-library/item,而不是 component-library/src/item(虽然目前可以工作))
    • How would I import a module within an npm package subfolder with webpack?
      • This is very nearly the correct approach I require, except that the import path used there involved the src/ directory, which I am trying to avoid (should be component-library/item, not component-library/src/item (which does work currently though))
      • 这正是我想要的,只是我希望没有构建"包中的阶段(依靠导入位置来构建/转换)
      1. 我可以在导入路径中以某种方式跳过 src/ 目录吗?
      2. 我可以跳过包中的任何类型的构建阶段吗(这样开发人员就不必在提交之前构建)?
      3. 类似于 material-ui 的包如何处理这个问题?

      推荐答案

      可能的解决方案之一是 webpack 别名系统.
      您可以创建另一个项目,例如将其命名为app-aliases",以便您的别名可以重复使用.
      该项目将有一个包含所有包路径的 js 文件:

      One of the possible solutions there is webpack aliasing system.
      You can create another project, call it for example 'app-aliases', so your aliases will be reusable.
      This project will has one js file with all of your packages paths:

      const path = require('path');
      
      module.exports = {
      '@components': path.resolve(__dirname, 'node_modules/components-library/src'),
      '@another': path.resolve(__dirname, 'node_modules/any/path/you/want'),
      }
      

      然后将其添加到任何负责构建/转译的项目中的 webpack 配置中:
      webpack.config.js

      And then add it to the webpack configuration in any project which will be responsible for building/transpiling:
      webpack.config.js

      const appAliases = require('app-aliases');
      
      const config = {
      ...
        resolve: {
          alias: {
            ...appAlises
          }
        }
      }
      

      在运行时代码中,您将能够像这样使用它:

      In the runtime code you will be able to use it like this:

      import {Button} from '@components/Button';
      import {Something} from '@another'
      

      如果您使用打字稿,则需要将相同的别名添加到 paths tsconfig 属性.
      所以你的问题的答案是:

      If you are using typescript you will need to add the same aliases to the paths tsconfig property.
      So answers to your questions are:

      1. 是的,您可以在别名中使用任何路径
      2. 是的,没有必要构建所有项目
      3. 我看到现在 mui 使用从 Directi 包(例如核心)导入,请参阅 https://material-ui.com/components/radio-buttons/import Radio from '@material-ui/core/Radio';.但我希望他们使用我在下面描述的重新导出.
      1. Yes, you can use any path in aliases
      2. Yes, it is not necessary to build all of your projects
      3. I see that now mui uses imports from directi packages (core for example), see https://material-ui.com/components/radio-buttons/ there is import Radio from '@material-ui/core/Radio';. But I hope they using re-export that I described below.

      还有关于node.js解析机制.
      当您导入某个库时,它会尝试在其中查找 node_modules/some-library/package.jsonmain 属性.此属性应通向您的主要入口点.通常它是 src/index.js (如果还没有,你应该在 package.json 中设置它).在此文件中,您可以从内部文件结构中重新导出您想要的任何内容,并且无需完整路径即可使用它.有关示例,请参阅此 repo.

      Also about node.js resolution mechanism.
      When you import some library it tries to find node_modules/some-library/package.json and then main property inside it. This property should lead to your main entry point. Usually it is src/index.js (you should set it in package.json if it is no there yet). In this file you can re-export anything you want from internals file structure and will be able to use it without the full path. Please see this repo for some examples.

      这篇关于从 npm 包的子文件夹导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆