How to publish contents only of a specific folder? - npm

How to streamline npm release when I want to include only specific path(s)?
I have ./src and ./dist files in my repository. I want to effectively publish only the contents of ./dist + ./package.json.
Using .npmignore to ignore ./src will simply ignore the ./src folder. I want to include only the contents of ./dist, i.e. now user would need to do require('my-package/dist/something'). I want to make it require('my-package/something'). ./something is contained in ./dist.

The way I have done it at the moment is, I have created a bash script:
npm run build
cp package.json ./dist
# or, if you need to have package.json "main" entry different,
# e.g. for being able to use `npm link`, you need to replace "main" value:
# sed 's#"main": "./dist/index.js"#"main": "./index.js"#' package.json > ./dist/package.json
cd ./dist
npm publish

For cross-platform compatibilty use shx:
npm run build
shx cp package.json ./dist
shx cd ./dist
npm publish

Related

Recursively copy files cross-platform via npm script

We have within a package.json build script a copy command (no we cant quickly change that).
Is there any solution we can make this work multiplatform with the same syntax easily?
I looked in several npm copy packages, but they don't transpile from windows to unix paths.
We basically need something like:
"build": "doStuff && cp -r ../folder/ /dist/"
working for windows.
Any ideas?
For a cross-platform solution consider utilizing the shx package.
Firstly cd to your project directory and run the following command to install it:
npm i -D shx
Then redefine your build script in the scripts section of your package.json as follows:
"scripts": {
"build": "doStuff && shx cp -r ../folder/ ./dist/"
}

npm, avoid publishing of src dir without using .npmignore

The npm publish
command creates a tarball (with src dir) and publish it to registry.
is there a way to exclude the src dir avoiding use of .npmignore ?
npm provides no other built-in feature to achieve that, so a custom solution is required.
If you really don't want to use .npmignore to keep the src directory out of your published package, then consider utilizing pre and post hooks in your npm scripts instead.
The pertinent hooks are:
prepublishOnly: Run BEFORE the package is prepared and packed, ONLY on npm publish ...
postpublish: Run AFTER the package is published.
For *nix platforms
Add a prepublishOnly script to the scripts section of your package.json that moves the src directory to another location outside of your project directory prior to publishing.
Also, add a postpublish script that moves the src directory back to the project directory when publishing has completed.
Run npm publish (as per normal) to publish your package.
For instance:
package.json
...
"scripts": {
"prepublishOnly": "mv src/ ../",
"postpublish": "mv ../src .",
...
},
...
Note: You'll need to ensure that no other src folder/directory exists at the path location you choose to temporarily move the src directory to via your prepublish script.
Cross platform:
For a cross-platform solution consider utilizing shx. This package includes a portable mv command. In which case, configure your prepublish and postpublish scripts something like the following instead:
package.json
...
"scripts": {
"prepublishOnly": "shx mv src/ ../",
"postpublish": "shx mv ../src .",
...
},
...
You can use the files property in your package.json to explicitly include the files you want to publish.
{
"files": [
"dist",
"index.js"
]
}
As #RobC answer, there is no other way then a custom solution for avoid using .npmignore.
Since I’m using the publish command in a Jenkins pipeline, a solution is to create a temporary .npmignore while the publish step directly in the Jenkinsfile:
echo "src/" >> .npmignore
echo "*.js" >> .npmignore
echo "*.json" >> .npmignore
echo "Jenkinsfile" >> .npmignore
curl --insecure -u ${USERPASS} 'https://my-repo/api/npm/auth' >> /home/jenkins/.npmrc
npm publish --registry https:// my-repo/api/npm/npm-local/

Replicating `npm pack` behavior

I am trying to replicate the behavior of npm pack because it has a limitation where it does not write to stdout, it can only write to a local file (see this issue: https://github.com/npm/npm/issues/12039)
Now, I can tar the current directory and write to stdout like so:
tar --exclude='./node_modules/' -cv . | gzip > archive.tar.gz
however, when you extract npm pack tarballs, all the contents of a your package should be in a directory called 'package'.
So my question is - how can I tarball the current directory, but put the current directory inside a directory called 'package' before it gets archived?
Is there some tar -flag that lets you do that?
I did some legwork and as far as my testing goes, npm will accept a tarball with everything in the root, or everything in a subdirectory called 'package'.
To test the above theory, you can tar a NPM project directory with:
tar --exclude='node_modules' -c . > archive.tar
then install it somewhere else with
npm install /path/to/archive.tar
you can't install in the same project though, NPM will complain about circular deps, so install it in another project.

Is there's a command for yarn to install a subfolder?

Background:
We are using yarn in this project and we don't want to write our package.json scripts with a mix of npm/yarn commands.
I have a root directory which contains a few subfolders.
Each holds a different service.
I want to create a script in the root folder that npm install each of the services, one by one.
Question:
Do you know what would be the yarn alternative to npm install <folder>?
I'm looking for something like this psuedo command: yarn <folder>
You could use --cwd there is a git issue about this :
yarn --cwd "your/path" script
You can also use cd :
cd "your/path" && yarn script
To run yarn install on every subdirectory you can do something like:
"scripts": {
...
"install:all": "for D in */; do yarn --cwd \"${D}\"; done"
}
where
install:all is just the name of the script, you can name it whatever you please
D Is the name of the directory at the current iteration
*/ Specifies where you want to look for subdirectories. directory/*/ will list all directories inside directory/ and directory/*/*/ will list all directories two levels in.
yarn -cwd install all dependencies in the given folder
You could also run several commands, for example:
for D in */; do echo \"Installing stuff on ${D}\" && yarn --cwd \"${D}\"; done
will print "Installing stuff on your_subfolder/" on every iteration.
To run multiple commands in a single subfolder:
cd your/path && yarn && yarn some-script

How to get "node_modules" folder content back

I have deleted the folder: "node_modules" from root folder(gave the source code to someone) because I think this contain packages that we can get any time.
How can I get those files back?
thanks in advance!
Do you have a package.json in your directory? If so, you can run npm i to reinstall the project dependencies ( a.k.a bring back your node_modules ).
You must have a package.json in your source's root folder. If that's the case, do $ npm install, it will rebuild all modules.
If you don't have package.json, run $ npm init, add your modules, then run $npm install.