The Context
I have one main project which has multiple node projects inside that as subdirectories. each one with their own node_modules directories and package.json files. I want to have an npm script defined in my main package.json files which runs npm scripts from each of those projects concurrently.
The Code
My directory structure is like this:
main:
...
package.json
- sub-project-1
- ...
package.json
- sub-project-2
...
package.json
Sub-project-1/package.json:
...
"scripts": {
"start": "node run foo.js"
}
Sub-project-2/package.json:
...
"scripts": {
"start": "node run bar.js"
}
Main package.json:
...
"scripts": {
"start": "/* Here I want to do something like npm sub-project-1/ start && npm sub-project-2/ start */
}
Now, obviously I could copy and paste the commands in sub-project-1/package.json's start script and sub-project-2/package.json's start script into a bash script and run that instead. But I want to be able to change those npm start scripts without having to manually change the bash script every time. Is there a way to do this?
The following is not concurrent; however, you can change the npm start scripts with this approach.
I should mention also that it's not the world's most scalable approach. But it's simple, so I thought it might be helpful to share.
Here goes ...
Main package.json:
...
"scripts": {
"start": "cd Sub-project-1 && npm run start && cd ../Sub-project-2 && npm run start && cd ../ && <parent project start script here>"
}
With this script, you're just meandering through the sub projects and then coming back up to run the parent project's script.
1.You can also write a python script that parses all the package.jsons of the subdirectories and then generate the master package.json file
2.or You can also write a python script that parses all the package.jsons of the subdirectories and then generate a shellscript where the mater package.json
will call it in the "start".
Related
I use underscores.me as a starter template for any new theme I create. Previously I just used dart-sass to compile my scss files into css. However, I'm starting a new project and would like to use the package.json file included with underscores (Sassified and with Woo Commerce), but I'm a bit confused about the included CLI commands that are in the package.json.
The following scripts are taken from the generated package.json file:
"scripts": {
"watch": "node-sass sass/ -o ./ --source-map true --output-style expanded --indent-type tab --indent-width 1 -w",
"compile:css": "node-sass sass/ -o ./ && stylelint '*.css' --fix || true && stylelint '*.css' --fix",
"compile:rtl": "rtlcss style.css style-rtl.css",
"lint:scss": "wp-scripts lint-style 'sass/**/*.scss'",
"lint:js": "wp-scripts lint-js 'js/*.js'",
"bundle": "dir-archiver --src . --dest ../_s.zip --exclude .DS_Store .stylelintrc.json .eslintrc .git .gitattributes .github .gitignore README.md composer.json composer.lock node_modules vendor package-lock.json package.json .travis.yml phpcs.xml.dist sass style.css.map yarn.lock"
}
Here are my questions:
What is the main difference between "watch" and "compile:css"? If one watches Sass files for changes and then compiles to CSS, how is this any different from compile:css? Should they both be running?
Are these all scripts that should be running simultaneously during dev/coding? Or, are some supposed to be run only at specific times, such as "bundle" when I need to recompile certain files like JavaScript to compile a production version?
If these are not meant to all be running simultaneously, such as the "bundle" command, when is the ideal time to run this script and once it's run should I stop it or simply let it keep running in the background?
Would I only use "compile:rtl" if using languages written from right-to-left?
Since the linting commands check for errors in SCSS and JS, should those be run simultaneously during development as well, or only when you go to check work prior to deploying to production?
So assuming I do not need to compile:rtl, how would one use the remaining 5 scripts most effectively and efficiently?
I have a secret key called API_KEY that I want to access inside of package.json's scripts.
package.json
{
"scripts": {
"start": "web-ext run --api-key=API_KEY"
}
}
My .env file contains API_KEY:
API_KEY=abc123
How can I access the value of API_KEY inside package.json's scripts while still keeping it a secret because I need to push package.json publicly?
Currently, I do the following which works but not cross-platform:
package.json
{
"scripts": {
"start": "web-ext run --api-key=$API_KEY"
}
}
And when running start script I do it like:
API_KEY=abc123 npm start
This works thanks to Bash Programming Language but it doesn't work on Windows. I need to replace $API_KEY in start script with %API_KEY%. But I want it to be cross-platform. Is there any other way?
The only other viable answer to this I found so far is a bit hacky:
{
"scripts": {
"start": "web-ext run --api-key=$(grep API_KEY .env | cut -d '=' -f2)"
}
}
[https://stackoverflow.com/a/58038814/1822977]
For cross platform
1) You can use 'npm env-cmd' as a devDependencies.
Setting the environment from a file
Usage
Environment file ./.env
# This is a comment
API_KEY=abc123
Package.json
{
"scripts": {
"start": "env-cmd web-ext run"
}
}
2) You can use 'npm cross-env' as a devDependencies.
Run scripts that set and use environment variables across platforms
Usage
{
"scripts": {
"start": "cross-env API_KEY=abc123 web-ext run"
}
}
For Windows only
You can try something like this:
cmd /C "set API_KEY=abc123 && npm start"
As Viper_Sb says here:
/C exits the new cmd right away after running, if you produce output with the new one it will still be visible in the parent window.
You can opt to use /K in which case the new cmd window stays open at the end of the run.
You can simply require "dotenv" lib, and access var from process.env.{SOME_KEY}
I have Jest installed on my machine and typing jest from terminal results in tests from parent folers also getting executed. I want to run tests only from the current folder.
For e.g. if I go to c:/dev/app in terminal and type some-jest-command, it should only run files with .test.js present in the app folder. Currently, running jest command from app folder runs tests in parent folders too, which is not my desired behaviour.
By default, Jest will try to recursively test everything from whatever folder package.json is located.
Let's say you're in c:/dev/app, and your package.json is in c:. If your basic command to invoke Jest is npm test, then try with run npm test dev/app.
If you want to run the tests from a specific folder user the --testPathPattern jest flag. When setting up the npm script add the path to the folder as well. In your package.json add the flag in you npm scripts. Check the bellow code for an example.
"scripts": {
....
"test:unit": "jest --testPathPattern=src/js/tests/unit-tests",
"test:integration": "jest --testPathPattern=src/js/tests/integration"
....
},
If you want to watch as well for changes, use the watch flag:
{
...
"test:unit": "jest --watch --testPathPattern=src/js/tests/unit-tests",
...
}
After that open, the command line, change the directory where your project is and run the unit test.
npm run test:unit
or integration tests.
npm run test:integration
To only run testing in a specific directory and to coerce Jest to read only certain type of files(my example: 'ExampleComponent.test.js' with new Jest version #24.9.0 you must write exact "testMatch" in jest.config.json || package.json in "jest" part next "testMatch": [ "<rootDir>/src/__tests__/**/*.test.js" ],
This testMatch in my case hits all files with the prefix .test.js in tests/subdirectories/ and skips all other files like 'setupTest.js' and other .js files in 'mocks' subdirectory which is placed inside of 'tests' directory,so,my 'jest.config.json' looks like this
{
"setupFiles": [
"raf/polyfill",
"<rootDir>/setupTests.js"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"moduleNameMapper": {
"^.+\\.(css|less|scss|sass)$": "identity-obj-proxy"
},
"testMatch": [
"<rootDir>/src/__tests__/**/*.test.js"
]
}
Just adapt to your needs 'testMatch' regex.
A little note: This is for jest#24.9.0 && enzyme#3.10.0 if it matters to anyone.
I hope it will be useful to someone, cheers all.
--package.json
"scripts": {
"test": "jest"
}
--jest.config.js
module.exports = {
"testMatch": [
"<rootDir>/tests/unit/*.test.js"
]
}
From the root of your project, you can run jest <substring of files> and it will only run the test files which have the substring you added.
$ jest /libs/components
> [PASS] /libs/components/button.tsx
yarn:
yarn test nameoffolder
npm:
npm test nameoffolder
For example, if you have a folder named widget and you only want to run the tests in the widget folder you would run this command.
yarn:
yarn test widget
npm:
npm test widget
I am minifying multiple files in a folder using uglifyjs-folder in npm package.json like :
"uglifyjs": "uglifyjs-folder js -eyo build/js"
It is working as intended & minify all files in folder.
I want to remove any console.log & alert while minify but not able to find any option with uglifyjs-folderhttps://www.npmjs.com/package/uglifyjs-folder
Please help.
Short Answer
Unfortunately, uglifyjs-folder does not provide an option to silence the logs.
Solution
You could consider writing a nodejs utility script which utilizes shelljs to:
Invoke the uglifyjs-folder command via the shelljs exec() method.
Prevent logging to console by utilizing the exec() methods silent option.
The following steps further explain how this can be achieved:
Install
Firstly, cd to your project directory and install/add shelljs by running:
npm i -D shelljs
node script
Create a nodejs utility script as follows. Lets name the file: run-uglifyjs-silently.js.
var path = require('path');
var shell = require('shelljs');
var uglifyjsPath = path.normalize('./node_modules/.bin/uglifyjs-folder');
shell.exec(uglifyjsPath + ' js -eyo build/js', { silent: true });
Note: We execute uglifyjs-folder directly from the local ./node_modules/.bin/ directory and utilize path.normalize() for cross-platform purposes.
package.json
Configure the uglifyjs script inside package.json as follows:
{
...
"scripts": {
"uglifyjs": "node run-uglifyjs-silently"
...
},
...
}
Running
Run the script as per normal via the command line. For example:
npm run uglifyjs
Or, for less logging to the console, add the npm run --silent or shorthand equivalent -s option/flag. For example:
npm run uglifyjs -s
Notes:
The example gist above assumes that run-uglifyjs-silently.js is saved at the top-level of your project directory, (i.e. Where package.json resides).
Tip: You could always store run-uglifyjs-silently.js in a hidden directory named .scripts at the top level of your project directory. In which case you'll need to redefine your script in package.json as follows:
{
...
"scripts": {
"uglifyjs": "node .scripts/run-uglifyjs-silently"
...
},
...
}
uglify-folder (in 2021, now?) supports passing in terser configs like so:
$ uglify-folder --config-file uglifyjs.config.json ...other options...
and with uglifyjs.config.json:
{
"compress": {
"drop_console": true
}
}
And all options available here from the API reference.
I am trying to lint all my javascript files using jshint with an npm script command.
I am running on windows and no matter what wildcard I specify I can't seem to lint more than one file.
Referencing a specific file works:
"scripts": {
"lint": "jshint app/main.js"
}
But all of the following results in errors:
"scripts": {
// results in Can't open app/**/*.js'
"lint1": "jshint app/**/*.js",
// results in Can't open app/*.js'
"lint2": "jshint app/*.js",
// results in Can't open app/**.js'
"lint3": "jshint app/**.js",
}
Although you can't use the wildcards when running jshint as a script task in npm on windows, you can work around it. By default, if jshint is passed a directory, it will search that directory recursively. So in your case you could simply do:
"script": {
"lint": "jshint app"
}
or even
"script": {
"lint": "jshint ."
}
This will result in all files - including those in node_modules being linted - which is probably not what you want. The easiest way to get round that is to have a file called .jshintignore in the root of your project containing the folders and scripts you don't want linted:
node_modules/
build/
dir/another_unlinted_script.js
This is then a cross-platform solution for jshint as a script task in npm.