Npm package.json main and project structure

I have a problem with npm and the main field. I see the documentation, and as far as I understand, the main point I consider a different entry point than. /index.js. I have already tested a package in which all dist files are inside the root folder. I ignore src and test during the package phase using .npmignore, but I did not like the fact that creating and packaging the project checks the structure of all my files in the root folder of the package. So I changed the output to dist.

If I use the npm package and extract the file, I get the following structure:

/ dist -- index.js -- moduleA -- index.js package.json README.md 

So so good. But now I have to import it as follows:

 import {moduleA} from "myNpmModule/dist/moduleA"; 

But I do not want to have a dist folder in my import. So I install main in package.json

 "main": "dist/index.js" 

But still it does not work and only works when importing with dist. I am using npm 3.10.7 and node 6.7.0.

Can anyone help?

Hello

+5
source share
2 answers

It is hard to say for sure, not knowing the contents of your main index.js and moduleA , but usually this is done so that you do not import any specific file, and the directory containing package.json is like:

 import {moduleA} from "myNpmModule"; 

Now index.js , referenced as "main" in package.json , should import the rest of the modules and export them as its own module.exports properties.

For example, in dist/index.js :

 import {moduleA} from "./moduleA"; module.exports.moduleA = moduleA; 

and in your main code:

 import {moduleA} from "myNpmModule"; 

Something like this - with possible differences according to your own module structure.

In fact, I wrote a module that automatically does something similar by importing modules into subdirectories and exporting them as properties. I did not put it on npm because it was for my own use, when I publish it on npm , I will update this answer.

Update

Here is a working example of what I described above - from import changed to require() to avoid the need for a transpilation step.

Module

The module following my answer:

Project Structure:

 dist -- index.js -- moduleA -- index.js package.json moduleA.js 

dist/index.js Contents:

 var {moduleA} = require('./moduleA'); module.exports.moduleA = moduleA; 

dist/moduleA/index.js Contents:

 module.exports.moduleA = { info: 'This is what dist/moduleA/index.js exports as moduleA' }; 

package.json Contents:

 { "name": "nested-project-structure-example", "version": "0.0.1", "description": "An example for a Qaru answer", "main": "dist/index.js", "scripts": { "test": "node test.js" }, // ... } 

moduleA.js Contents:

 module.exports = require('./dist/moduleA'); 

Using

A project that uses this module:

It can be imported as follows:

Version 1
 var {moduleA} = require('nested-project-structure-example'); console.error(moduleA.info); 

This imports dist/moduleA/index.js through the dist/index.js file specified in package.json . See test1.js for a working example.

Version 2
 var {moduleA} = require('nested-project-structure-example/dist/moduleA'); console.error(moduleA.info); 

This imports dist/moduleA/index.js , directly knowing the internal path, including dist . See test2.js for a working example.

Version 3
 var {moduleA} = require('nested-project-structure-example/moduleA'); console.error(moduleA.info); 

This imports dist/moduleA/index.js through the moduleA.js file into the main directory of the project. Thus, you do not need to know the internal organization of the project - the dist path is not required. See test3.js for a working example.

The whole moduleA.js project in the project:

 module.exports = require('./dist/moduleA'); 

Without such a file in the project root directory, you cannot import moduleA without including dist in your path, or import it directly through the main js file of your project, included in package.json ( dist/index.js in this case).

These are 3 ways to achieve the goal of your question, two of which do not include dist in the code that the module imports. I hope he answers your question.

These are the only options you have, without dividing your module into a set of completely separate modules, each of which is distributed separately.

+2
source

So here is what I understand how this works. I am not sure if this is true. I got this understanding from simple observations and reasoning, and not from actually observing this in the dock. assumption 1 (package.json):

 {... "name": "my-package", "main": "dist/index.js", "scripts": { "build": "babel src --out-dir dist", "prepublish": "npm run build" }... } 

Assumption 2 (packaging structure):

 / -- dist -- moduleA -- index.js -- moduleAA -- index.js -- moduleB -- index.js 

performing the above steps:

 var myPackage = require("my-package"); var moduleAA = myPackage.moduleA.moduleAA; // or in short var moduleAA = require("my-package").moduleA.moduleAA; 

however, it looks like this:

 import moduleA from "my-package/moduleA/moduleAA"; 

not equivalent to the application using the requirement above. What could you do instead of id:

 import { moduleA } from "my-pakage"; const moduleAA = moduleA.moduleAA; 

Assuming you still want to have direct import from the AA module with the above project structure, you would need:

 import moduleAA from "my-package/dist/moduleA/moduleAA"; 

So, here is my conclusion and how I understand it.

... from "my-package / dist / moduleA / moduleAA"; doesn't look at the project structure in terms of JS / npm (which is exported), but instead it looks at the structure of the package file as soon as you use / in the phrase.

That means if you use

 import { moduleA } from "my-pakage"; 

it actually imports the entire export from dist / index.js, but if you import "my-package / moduleA", it actually scans the package if the path "/ moduleA" exists. In the above case this is not true. If we omit the dist folder and move the structure to the root of the package, this statement will work as you expected.

So no one can ask why I want this stuff to be in the dist folder? Git is easy to ignore. As far as I understand best practice using node, you use the "prepublish" step to create your package. this means that if you do a new code check and run "npm install", which performs "npm run prepublish" by design, it spam the folder structure with packed and converted files.

After playing with this for several hours, I gave up and simply admitted that "npm install" could potentially spam my folders. Alternatively, I could not define prepublish in my package.json and just run "npm run build" before "npm publish". ("scripts": {"build": "babel src -out-dir."})

+1
source

Source: https://habr.com/ru/post/1257382/


All Articles