I have a lerna repo that contains multiple packages organised in the usual structure:
package.json
/packages
- alpha
package.json
- bravo
package.json
- charlie
package.json
I need to transpile all packages, and I currently have the following scripts in each package's package.json:
"build": "npm run build:noWatch -- --watch --verbose",
"build:noWatch": "babel src --out-dir lib --root-mode upward --ignore '**/*.test.js','**/__tests__'",
"prebuild": "rimraf lib/*"
I currently run a build using:
lerna run build --stream --parallel
However I don't want to duplicate these scripts for every package. I would like to define the scripts in a single place, but use them from all packages. I currently have linting scripts and testing scripts in my root package which make sense there as they are effectively traversing the whole monorepo looking for tests, or files to lint. It doesn't seeem to make sense to move the build scripts up there as well as they are scoped to the individual packages, and I like the fact that I get different colour output for each package when I use lerna run.
An unsatisfying solution is to create some shell scripts in the root of the monorepo and call them from the packages' package.json files:
In root/packages/example/package.json:
"scripts": {
"build": "../../scripts/build.sh",
"build:noWatch": "../../scripts/build.sh",
"prebuild": "../../scripts/prebuild.sh"
},
Then in root/scripts/build.sh:
#!/bin/sh
babel src --out-dir lib --root-mode upward --ignore '**/*.test.js','**/__tests__' --watch --verbose
Whilst this works, it doesn't feel right: it still involves duplication between the packages and requires setting permissions on the shell scripts (which complicates CI).
Is there a better way to share these commands amongst all my packages?
Package all the build scripts into their own module and then use lerna --hoist to host the common module so it is installed once but available to all the other packages.
Related
Here is the scenario
I have multiple angular applications which belong to the same project. When I needed to upgrade an npm package, I need to change all the package.json files in each application. I tried mono repo, but it does not apply to my project because npm scripts are not the same as all apps.
So I want to separate the node dependencies from applications and keep npm scripts of the package.json files.
Is there a way to separate only the dependencies object from the package.json file? OR any other suggestions?
If I understood well this could not be done with npm but seems like it can be achieved with yarn workspaces:
https://classic.yarnpkg.com/en/docs/workspaces/
Guide for installing yarn:
https://classic.yarnpkg.com/en/docs/install/
Unfortunately npm do not support package.json inheritance. See this link.
On the other side why don't you customize your npm scripts? create alias for every npm command.
e.g.
"test-app1": "ng test app1",
"test-app2": "ng test app2 --code-coverage --no-watch --no-progress --browsers ChromeHeadlessNoSandbox",
I can use parcel index.html to create a local development server, bundling and hot module replacement. But it have come to my attention that using npm run dev does kind of the same think, so my question is:
what is the difference between the two? and how npm run dev is making the bundling process?
NPM vs Parcel isn't a valid comparison. They are two separate things. You can use Parcel with both NPM and Yarn.
Parcel is a web application bundler that is comparable to Webpack
NPM is a package management system for node.
npm run * is a command that will execute any npm script specified within your package.json and has no exclusivity to Parcel. You can of course make an npm script that will execute Parcel commands.
If you go into your package.json file, you will see a scripts property. Within this object, you can define arbitrary scripts to run. There are reserved script names such as start, install, build among others, but for the most part, this is a "free-for-all" that enabled the developer to specify any arbitrary scripts to run. A few common scripts that you'll typically see scripts to bundle your project or run a linter.
Example of package.json
Webpack Example:
{
"scripts": {
"build": "webpack --config <your entry file>"
}
}
Parcel Example:
{
"scripts": {
"build": "parcel build <your entry file>"
}
}
I've cloned this repository:
https://github.com/Microsoft/TypeScript-Vue-Starter
I run npm scripts:
npm install
npm run build
The result: build.js filzesize is about 1MB.
For a simple example, why is build.js so much bigger than the Vue.js library?
Notice that Webpack 2 is installed in package.json.
You will have to optimize the bundle yourself through the webpack.config.js and manage environment variables to reduce the bundle size.
Alternatively, you can install Webpack 4 instead and change the build script to:
"build": "webpack --mode production"
Webpack will take care of optimizing the bundle with sensible defaults.
Reference
Hi I use npm install jquery to install a jQuery for my project.but i find it is located in node_modules\jquery with many unwanted files.
but I just wana put node_modules\jquery\dist\jquery.min.js into static\jquery folder
what is the best and common way? copy and paste manually?
You can use npm to do this. In your package.json, add the following to the scripts key
...
"scripts": {
"build:jquery": "cp node_modules/jquery/dist/jquery.slim.min.js static/jquery/"
},
...
Then you can run: npm run build:jquery
You can add more build tasks to this section as you need them such as copying images and minifying scripts and css, then chain them together in a single command with npm-run-all:
$ npm install npm-run-all --save-dev
And...
...
"scripts": {
"build:jquery": "cp node_modules/jquery/dist/jquery.slim.min.js static/jquery/",
"build:images": "cp -R src/assets/images/ static/images/",
"build": "npm-run-all -p build:*"
},
...
Then run npm run build
npm is a great build tool and often bypasses the need for an additional build framework such as Gulp or Grunt. It can also handle file watchers and such to rebuild when things are modified automatically.
I saw many repo, that contains dist folder. Why? I think repo should store only source code, without any builds and so on.
Let's look at follow example with ES6 code.
package.json
{
"files": [
"dist",
"lib"
],
"scripts": {
"build:lib": "<transform ES6 to ES5 and put it to ./lib folder>",
"build:umd": "<make a umd module and put it ./dist folder>",
"build": "npm run build:lib && npm run build:umd",
"postbuild": "<make minify code>"
"prepublish": "npm run build"
}
}
I think this is a good way. And I saw several repo that do the same. In this situation github repo would store only src and npm repo only lib and dist.
And now another question. Why store dist and lib in npm? Most libraries can be installed by executing npm install command. And how we know prepublish script runs on local npm install (npm-scripts).
So after package have installed we have lib and dist folders.
I don't understand why store this code in npm if only source code is enough?
It appears that repositories include dist directories in order to enable other projects to use them as direct dependencies via git. Compare package.json docs, though as of now this doesn't mention that artefacts need to be present.
Compare NPM: Missing dist and src directories when trying to install directly from a github url for the problem that arises if the dist directory is not checked in.
Alternatively, it is also possible to install from a Git repository directly as long as a prepare stage which builds the package is provided:
{
...
"scripts": {
...
"prepare": "npm run build"
},
...
}
This way, you won't have to store /dist folder in the repository itself