Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
143
rated 0 times [  145] [ 2]  / answers: 1 / hits: 35043  / 7 Years ago, sat, june 3, 2017, 12:00:00

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.


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.


Directory Structure


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

Other Project


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

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.


Similar Questions



Questions



  1. Can I skip the src/ directory somehow in the import path?

  2. Can I skip any type of build phase in the package (so developers don't have to build before committing)?

  3. How does a package similar to material-ui handle this?


More From » node.js

 Answers
1

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'),
}


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'


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. 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.



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.


[#57572] Thursday, June 1, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
madilynndiannac

Total Points: 191
Total Questions: 93
Total Answers: 111

Location: France
Member since Thu, Oct 15, 2020
4 Years ago
;