Pack npm files independent of their directory? - npm

I have an npm project that builds multiple files to the public folder: an index.js file as well as several sub-files that I want to be conveniently accessible to the implementer.
My file structure on my machine looks like this:
|-public/
|--- index.js
|--- component1.js
|--- component2.js
My package.json is set up to include everything in the public folder in its tarball:
{
...
"main": "public/index.js",
"files": [ "public" ]
...
}
When I run the npm pack command, the resulting structure of the tarball looks like this:
|- package/
|--- public/
|------ index.js
|------ component1.js
|------ component2.js
|--- package.json
But in my package folder, I'd like everything to be on the same root level so that my implementer can just type import Component1 from "my-package-name/component1"; to get the sub-component. Is there a way to configure my package.json or npm to pack my project into the following structure?
|- package/
|--- index.js
|--- component1.js
|--- component2.js
|--- package.json

I ended up accomplishing this by moving my package.json file to my /public folder, then packing and publishing from that folder instead, then moving package.jsonback. If you can automate this process with a script, it is not too much of an inconvenience.

Related

Exporting Sass in NPM module

I am trying to build an NPM module that will allow an SCSS file to be exported and used across a number of applications.
The SCSS file imports another SCSS in another seperate node module.
My package structure is:
package-name
|--src
| |- overwrite.scss
|
|--package.json
|
|--webpack.config.js
|
|--node_modules
The issue I am facing is that currently I have the paths hardcoded for the import value. For example
$background-color: red;
#import '../node_module/fake_name/dist/core.scss'
I have a dependency in package.json file to ensure that fake_name module will always be in the node_modules folder of any project that will use my npm package.
What I am trying to achieve is set it that the path of #import will always look in the node_modules folder in the root of whatever project it is installed in. I have tired using ~ but I keep getting 'Error: File to import not found or unreadable'
Any help is appreciated.

Using Node Modules in Simple Project

I have a very simple web project and I'm using npm init to create the package.json file for the project. My project structure is below:
ProjectFolder
--app /this is the folder for js files
--css
--scss
--lib /this is for files like jQuery
--index.html
When adding a node package, it will create a node_modules folder like this:
ProjectFolder
--node_modules
--app /this is the folder for js files
--css
--scss
--lib /this is for files like jQuery
--index.html
Let's say I add jquery through npm install and make it a dependency. Is it good practice to link to the jquery file in node_modules from my index.html or move the jquery file to my lib folder?
Is there a way to move the jquery file to my lib folder when installing?
I don't want to move the node_modules folder to the server and want to know the best practice.
Your package.json is essentially your link. It contains a list of the packages you are dependent on and their versions. If you install something using npm install it has to be a published npm package on an npm repository somewhere (either public or private). It downloads a zipped version of the npm package and unzips it into node_modules. Anything in there is automatically then available to your app. Hope that helps.

How to prevent inheriting packages from parent node_modules

First I will give some context to the problem.
I am developing an npm library. Inside the project folder, I have another folder called "example", for testing the library. The structure looks like below.
|- node_modules/
|- src/
|- example/
| |- node_modules/
| |- src/
| |- package.json
|- package.json
The root package.json has the dependency babel-jest. The example/package.json has the dependency react-scripts. When running react-scripts start inside example directory, it gives the following error,
As far as I can understand, this is because, the package.json inside the example/ directory inherits (not sure if this is the right term) the dependencies of the root package.json.
That is, I can use a dependency installed in the root package.json, inside the src/ of the example/
This is convenient in some cases. But this is a blocker for my use case.
How can I prevent this behaviour? (without changing the directory structure)
Thank you.
From what I understand, Dan Abramov suggests to use SKIP_PREFLIGHT_CHECK=true to work around this problem as there is no real fix.

Electron-Builder does not copy node_modules into my application

I have an electron app with the following structure
- dist
| - index.html
| - node_modules
| - nm (is an exact copy of node_modules)
- package.json
| ...
if I refer to the node modules in my index.html as node_modules/module the app won't find the module if built with the build command from electron-builder. But if I change that line in my index.html to nm/module it is perfectly willing to load it.
It seems to me that electron-builder isn't copying node_modules into the application, but I can't see why it would do that. Is it excluding all folders named node_modules and how can I fix this?

Import local packages as modules not in the React-Native project

In a React-Native project, I found that if your local package has a valid package.json file, you can import that like a module in node_modules without a relative path .
For example,
app/ # a React-Native project
|- any_folder_for_packages/
| |- foo/
| |- package.json
| |- index.js
|- src/
| |- bar/
| |- bar.js
|- ...
In this case, you can import the package foo in the bar.js using either:
// with a relative path
import foo from '../../any_folder_for_packages/foo';
or
// like a module (without a relative path)
import foo from 'foo';
The packager will try to find and use any local module which contains a package.json matching the requirement.
The question
I have a local package which is not in the React-Native project, how can I import it
projects/
|- app/ # a React-Native project
| |- src/
| | |- bar/
| | |- bar.js # need to import the package foo as a module which is not in this project
| |- ...
|- other_paths/
|- foo/
|- package.json
|- index.js
I tried to use
// like a module (without a relative path)
import foo from 'foo';
but it failed to find the module.
How can I use react-native to find the package when packing for development or bundling for the production?
Answer given by #Plague doesn't work in react native. You have to configure your metro.config.js file to use a local package.
If Using Expo
In expo, metro.config.js file may not be visible, so in the root directory of your project, run this command;
npx expo customize metro.config.js
This will generate the file for you with some default configuration. Now to import any package, you have to modify two things here;
config.resolver.nodeModulesPaths, to include the package, and ;
config.watchFolders to keep a watch on the package.
In nutshell, metro.config.js file should be like this;
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
const config = getDefaultConfig(__dirname);
const packagePath = "/full/path/to/package";
// here i added the packagePath to the list in the configuration to include it
config.resolver.nodeModulesPaths.push(packagePath);
// here i added the package again to another configuration key, to keep a watch on it if we make any changes.
config.watchFolders.push(packagePath);
module.exports = config;
That is it, but your code editor may report that module is not found, for that warning to remove, you can just run the command below;
npm install /path/to/package
BUT there is a problem with this
The dependencies in our package conflicts with that of main project.
So here is another way of installing a local package.
Using install-local
For this we don't need to make any changes to any file. We just need to install this package;
npm install install-local
And then install the local package using this;
npx install-local --save path/to/package
You will need to make your application aware of it through your root package.json files.
Confirm the new local module has a basic package.json configured.
For example:
{
"name": "foo",
"version": "0.0.1"
}
Ensure the package has an index.js and that it has something exported or export default.
For example, at the bottom of the index.js:
export default foo;
Then, simply save the package as a project dependency in your root module to via NPM. To do this and install it automatically into your node_modules you can use this command.
npm install --save file:other_paths/foo
note make sure you have the correct relative path from your general project package.json to your new module package.json.
Example, in this case it would be:
app/ # a React-Native project root
|- other_paths/
| |- foo/
| |- package.json # new module package json
| |- index.js
|- src/
| |- bar/
| |- bar.js
|- package.json # project package json
If set up correctly you should then be able reference the module anywhere in your project without relative path.
import Foo from 'foo';