Create vendor.js bundle with pure npm script - javascript

I am trying out the modern approach to build javascript applications without Grunt or Gulp. I am creating my build utilities by just using the scripts key word in package.json.
It works great, but I ran into a challenge. Is there a good way to create separate vendor.js and app.js bundles without making every dependency explicit in the browserify command (or alternatively passing a list of deps to the browserify command)?
Something better than:
"dependencies": {
"react": "latest",
"react-dom": "latest",
"redux": "latest",
"d3": "latest"
},
"devDependencies": {
"browserify": "latest"
},
"scripts": {
"vendor": "browserify -r react -r react-dom -r redux -r d3 > vendor.js",
"app": "browserify -x react -x react-dom -x redux -x d3 ./app/main.js > app.js"
}
Preferable, I would recycle the information stored in the dependencies keyword. Obviously, I do not want bundle devDependencies or dependencies not used in my code (even though the latter can be prevented by good maintenance of the requirements).

Yes, it is possible. Whether the solution is very elegant, I'll leave up to you to decide. Basically it boils down to something like the following (incomplete, browserify not yet called) snippet:
"scripts": {
"init": "npm ls -json --depth 0 | jq .dependencies | jq keys[]",
"vendor": "npm run --silent init | sed 's/\\(.*\\)/-r \\1/g' | xargs"
},
The init script is used to extract the dependencies. The vendor script calls this script, and converts it to the input parameters for browserify.
Note 1: I'm using jq to extract information from the dependencies tree.
Note 2: construction of the argument list can also be done in the init script. You will have to provide an environment variable to distinguish between the -r or -x options.

Related

Angular / node.js how to copy the app version from package.json to anothe non json file

Within my Angular app , and while building it , i ve to catch the app version , which is inside my package.json file and copy it to another file which would be not a json file.
My package.json file :
{
"name": "my app",
"author": "ME",
"version": "0.1.3",
"scripts": {
"ng": "ng",
"start": "ng serve --public-host --port 4222 http://localhost:4222/",
"build": "ng build",
"sync-version": "sync-json -v --property version --source package.json projects/cockpit-tools/package.json && sync-json -v --property version --source package.json projects/cockpit-tools-demo/src/assets/configuration/properties.json",
"sync-custom": "shx node -p -e \"require('./package.json').version\"",
"copy-version":"MY_COMMAND"
...
}
My target file is properties file whih looks like this , and which is located in same path of package.json (this file is used in another level of automation , that's why i can't change it)
app-infos.properties
project.version=0.0.0
project.author=ME
My purpose is to write a command line task script which i may run to synchronize / copy the version from package.json to the project.version property inside my target file.
I ve tried an npm library called sync-version , but that works only when the target is a json file
I ve tried also to do it with shell command line within the shx package. also that didn't work as expected.
i ve also tried some node.js tricks (require ...) but the problem persists
i need to find a way to do it with the simpliest way and not be obliged to install some linux tools or similar(jq or other) , since this would run in some CI CD contexts , so that would rather to be as native and as generic as possible.
Suggestions ?
A classic DevOps situation :)
CI/CD usually happens on linux envs.
You will probably have plain shell/bash.
Try extractinf the version to a variable:
myVersion=`grep 'version:' package.json | awk '{print $2}'`
then replacing it in the apps-info:
sed -i "s/0.0.0/$myVersion/" apps-info.properties
We can make ot more generic by always pulling the last version instead of 0.0.0,
but i think you should have a place holder like 0.0.0

'ENV' is not recognized as an internal or external command, [duplicate]

How to set some environment variables from within package.json to be used with npm start like commands?
Here's what I currently have in my package.json:
{
...
"scripts": {
"help": "tagove help",
"start": "tagove start"
}
...
}
I want to set environment variables (like NODE_ENV) in the start script while still being able to start the app with just one command, npm start.
Set the environment variable in the script command:
...
"scripts": {
"start": "node app.js",
"test": "NODE_ENV=test mocha --reporter spec"
},
...
Then use process.env.NODE_ENV in your app.
Note: This is for Mac & Linux only. For Windows refer to the comments.
Just use NPM package cross-env. Super easy. Works on Windows, Linux, and all environments. Notice that you don't use && to move to the next task. You just set the env and then start the next task. Credit to #mikekidder for the suggestion in one of the comments here.
From documentation:
{
"scripts": {
"build": "cross-env NODE_ENV=production OTHERFLAG=myValue webpack --config build/webpack.config.js"
}
}
Notice that if you want to set multiple global vars, you just state them in succession, followed by your command to be executed.
Ultimately, the command that is executed (using spawn) is:
webpack --config build/webpack.config.js
The NODE_ENV environment variable will be set by cross-env
I just wanted to add my two cents here for future Node-explorers. On my Ubuntu 14.04 the NODE_ENV=test didn't work, I had to use export NODE_ENV=test after which NODE_ENV=test started working too, weird.
On Windows as have been said you have to use set NODE_ENV=test but for a cross-platform solution the cross-env library didn't seem to do the trick and do you really need a library to do this:
export NODE_ENV=test || set NODE_ENV=test&& yadda yadda
The vertical bars are needed as otherwise Windows would crash on the unrecognized export NODE_ENV command. I don't know about the trailing space, but just to be sure I removed them too.
Because I often find myself working with multiple environment variables, I find it useful to keep them in a separate .env file (make sure to ignore this from your source control). Then (in Linux) prepend export $(cat .env | xargs) && in your script command before starting your app.
Example .env file:
VAR_A=Hello World
VAR_B=format the .env file like this with new vars separated by a line break
Example index.js:
console.log('Test', process.env.VAR_A, process.env.VAR_B);
Example package.json:
{
...
"scripts": {
"start": "node index.js",
"env-linux": "export $(cat .env | xargs) && env",
"start-linux": "export $(cat .env | xargs) && npm start",
"env-windows": "(for /F \"tokens=*\" %i in (.env) do set %i)",
"start-windows": "(for /F \"tokens=*\" %i in (.env) do set %i) && npm start",
}
...
}
Unfortunately I can't seem to set the environment variables by calling a script from a script -- like "start-windows": "npm run env-windows && npm start" -- so there is some redundancy in the scripts.
For a test you can see the env variables by running npm run env-linux or npm run env-windows, and test that they make it into your app by running npm run start-linux or npm run start-windows.
Try this on Windows by replacing YOURENV:
{
...
"scripts": {
"help": "set NODE_ENV=YOURENV && tagove help",
"start": "set NODE_ENV=YOURENV && tagove start"
}
...
}
#luke's answer was almost the one I needed! Thanks.
As the selected answer is very straightforward (and correct), but old, I would like to offer an alternative for importing variables from a .env separate file when running your scripts and fixing some limitations to Luke's answer.
Try this:
::: .env file :::
# This way, you CAN use comments in your .env files
NODE_PATH="src/"
# You can also have extra/empty lines in it
SASS_PATH="node_modules:src/styles"
Then, in your package json, you will create a script that will set the variables and run it before the scripts you need them:
::: package.json :::
scripts: {
"set-env": "export $(cat .env | grep \"^[^#;]\" |xargs)",
"storybook": "npm run set-env && start-storybook -s public"
}
Some observations:
The regular expression in the grep'ed cat command will clear the comments and empty lines.
The && don't need to be "glued" to npm run set-env, as it would be required if you were setting the variables in the same command.
If you are using yarn, you may see a warning, you can either change it to yarn set-env or use npm run set-env --scripts-prepend-node-path && instead.
Different environments
Another advantage when using it is that you can have different environment variables.
scripts: {
"set-env:production": "export $(cat .production.env | grep \"^[^#;]\" |xargs)",
"set-env:development": "export $(cat .env | grep \"^[^#;]\" |xargs)",
}
Please, remember not to add .env files to your git repository when you have keys, passwords or sensitive/personal data in them!
UPDATE: This solution may break in npm v7 due to npm RFC 21
CAVEAT: no idea if this works with yarn
npm (and yarn) passes a lot of data from package.json into scripts as environment variables. Use npm run env to see them all. This is documented in https://docs.npmjs.com/misc/scripts#environment and is not only for "lifecycle" scripts like prepublish but also any script executed by npm run.
You can access these inside code (e.g. process.env.npm_package_config_port in JS) but they're already available to the shell running the scripts so you can also access them as $npm_... expansions in the "scripts" (unix syntax, might not work on windows?).
The "config" section seems intended for this use:
"name": "myproject",
...
"config": {
"port": "8010"
},
"scripts": {
"start": "node server.js $npm_package_config_port",
"test": "wait-on http://localhost:$npm_package_config_port/ && node test.js http://localhost:$npm_package_config_port/"
}
An important quality of these "config" fields is that users can override them without modifying package.json!
$ npm run start
> myproject#0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port
Serving on localhost:8010
$ npm config set myproject:port 8020
$ git diff package.json # no change!
$ cat ~/.npmrc
myproject:port=8020
$ npm run start
> myproject#0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port
Serving on localhost:8020
See npm config and yarn config docs.
It appears that yarn reads ~/.npmrc so npm config set affects both, but yarn config set writes to ~/.yarnrc, so only yarn will see it :-(
For a larger set of environment variables or when you want to reuse them you can use env-cmd.
As a plus, the .env file would also work with direnv.
./.env file:
# This is a comment
ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH
./package.json:
{
"scripts": {
"test": "env-cmd mocha -R spec"
}
}
This will work in Windows console:
"scripts": {
"setAndStart": "set TMP=test&& node index.js",
"otherScriptCmd": "echo %TMP%"
}
npm run aaa
output:
test
See this answer for details.
suddenly i found that actionhero is using following code, that solved my problem by just passing --NODE_ENV=production in start script command option.
if(argv['NODE_ENV'] != null){
api.env = argv['NODE_ENV'];
} else if(process.env.NODE_ENV != null){
api.env = process.env.NODE_ENV;
}
i would really appreciate to accept answer of someone else who know more better way to set environment variables in package.json or init script or something like, where app bootstrapped by someone else.
use git bash in windows. Git Bash processes commands differently than cmd.
Most Windows command prompts will choke when you set environment variables with NODE_ENV=production like that. (The exception is Bash on Windows, which uses native Bash.) Similarly, there's a difference in how windows and POSIX commands utilize environment variables. With POSIX, you use: $ENV_VAR and on windows you use %ENV_VAR%. - cross-env doc
{
...
"scripts": {
"help": "tagove help",
"start": "env NODE_ENV=production tagove start"
}
...
}
use dotenv package to declare the env variables
For single environment variable
"scripts": {
"start": "set NODE_ENV=production&& node server.js"
}
For multiple environment variables
"scripts": {
"start": "set NODE_ENV=production&& set PORT=8000&& node server.js"
}
When the NODE_ENV environment variable is set to 'production' all devDependencies in your package.json file will be completely ignored when running npm install. You can also enforce this with a --production flag:
npm install --production
For setting NODE_ENV you can use any of these methods
method 1: set NODE_ENV for all node apps
Windows :
set NODE_ENV=production
Linux, macOS or other unix based system :
export NODE_ENV=production
This sets NODE_ENV for current bash session thus any apps started after this statement will have NODE_ENV set to production.
method 2: set NODE_ENV for current app
NODE_ENV=production node app.js
This will set NODE_ENV for the current app only. This helps when we want to test our apps on different environments.
method 3: create .env file and use it
This uses the idea explained here. Refer this post for more detailed explanation.
Basically, you create a .env file and run some bash scripts to set them on the environment.
To avoid writing a bash script, the env-cmd package can be used to load the environment variables defined in the .env file.
env-cmd .env node app.js
method 4: Use cross-env package
This package allows environment variables to be set in one way for every platform.
After installing it with npm, you can just add it to your deployment script in package.json as follows:
"build:deploy": "cross-env NODE_ENV=production webpack"
{
...
"scripts": {
"start": "ENV NODE_ENV=production someapp --options"
}
...
}
Most elegant and portable solution:
package.json:
"scripts": {
"serve": "export NODE_PRESERVE_SYMLINKS_MAIN=1 && vue-cli-service serve"
},
Under windows create export.cmd and put it somewhere to your %PATH%:
#echo off
set %*
If you:
Are currently using Windows;
Have git bash installed;
Don't want to use set ENV in your package.json which makes it only runnable for Windows dev machines;
Then you can set the script shell of node from cmd to git bash and write linux-style env setting statements in package.json for it to work on both Windows/Linux/Mac.
$ npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"
Although not directly answering the question Iยดd like to share an idea on top of the other answers. From what I got each of these would offer some level of complexity to achieve cross platform independency.
On my scenario all I wanted, originally, to set a variable to control whether or not to secure the server with JWT authentication (for development purposes)
After reading the answers I decided simply to create 2 different files, with authentication turned on and off respectively.
"scripts": {
"dev": "nodemon --debug index_auth.js",
"devna": "nodemon --debug index_no_auth.js",
}
The files are simply wrappers that call the original index.js file (which I renamed to appbootstrapper.js):
//index_no_auth.js authentication turned off
const bootstrapper = require('./appbootstrapper');
bootstrapper(false);
//index_auth.js authentication turned on
const bootstrapper = require('./appbootstrapper');
bootstrapper(true);
class AppBootStrapper {
init(useauth) {
//real initialization
}
}
Perhaps this can help someone else
Running a node.js script from package.json with multiple environment variables:
package.json file:
"scripts": {
"do-nothing": "set NODE_ENV=prod4 && set LOCAL_RUN=true && node ./x.js",
},
x.js file can be as:
let env = process.env.NODE_ENV;
let isLocal = process.env.LOCAL_RUN;
console.log("ENV" , env);
console.log("isLocal", isLocal);
You should not set ENV variables in package.json. actionhero uses NODE_ENV to allow you to change configuration options which are loaded from the files in ./config. Check out the redis config file, and see how NODE_ENV is uses to change database options in NODE_ENV=test
If you want to use other ENV variables to set things (perhaps the HTTP port), you still don't need to change anything in package.json. For example, if you set PORT=1234 in ENV and want to use that as the HTTP port in NODE_ENV=production, just reference that in the relevant config file, IE:
# in config/servers/web.js
exports.production = {
servers: {
web: function(api){
return {
port: process.env.PORT
}
}
}
}
In addition to use of cross-env as documented above, for setting a few environment variables within a package.json 'run script', if your script involves running NodeJS, then you can set Node to pre-require dotenv/config:
{
scripts: {
"eg:js": "node -r dotenv/config your-script.js",
"eg:ts": "ts-node -r dotenv/config your-script.ts",
"test": "ts-node -r dotenv/config -C 'console.log(process.env.PATH)'",
}
}
This will cause your node interpreter to require dotenv/config, which will itself read the .env file in the present working directory from which node was called.
The .env format is lax or liberal:
# Comments are permitted
FOO=123
BAR=${FOO}
BAZ=Basingstoke Round About
#Blank lines are no problem
Note : In order to set multiple environment variable, script should goes like this
"scripts": {
"start": "set NODE_ENV=production&& set MONGO_USER=your_DB_USER_NAME&& set MONGO_PASSWORD=DB_PASSWORD&& set MONGO_DEFAULT_DATABASE=DB_NAME&& node app.js",
},

Lambda function with additional dependencies

I'm starting a CDK lambda project which gets the source code like this:
code: lambda.Code.fromAsset("resources"),
handler: "synthetic_test.main",
There's a single javascript file synthetic_test.js in that folder.
This seems to work but I can't figure out how to make it so that I could do:
const axios = require("axios");
in that file.
For some reason it seems to be able to import:
const AWS = require("aws-sdk");
but nothing else.
I did yarn add axios which added it to the package.json of my CDK project. But that does not really seem to help the lambda a lot.
The AWS Lambda runtime environment includes native language libraries and the relevant language-specific AWS SDK.
It does not contain arbitrary third-party packages. You need to either package those dependencies with your code or create a Lambda Layer that includes the dependencies and configure your Lambda function to use the Lambda Layer.
To package CDK app dependencies, see #aws-cdk/aws-lambda-nodejs and here.
I went with packaging dependencies with my code
My cdk went to
// ๐Ÿ‘‡ define PUT account function
const putAccountLambda = new lambda.Function(this, "put-account-lambda", {
runtime: lambda.Runtime.NODEJS_14_X,
handler: "main.handler",
code: lambda.Code.fromAsset(path.join(__dirname, "/../src/put-account/dist")),
environment: {
REGION,
ADMINS_TABLE,
ADMINS_TABLE_PARTITION_KEY,
HASH_ALG,
}
})
With dist being the folder with a packed main.js file. And this file has a handler entrypoint. I had to update the package.json of these lambdas with packed dependencies.
{
"name": "put-account",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode=production --env env=prod",
"build:dev": "webpack --mode=development --env env=dev"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.66.0",
"webpack-cli": "^4.9.1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"aws-sdk": "^2.1058.0",
"crypto": "^1.0.1",
"uuid": "^8.3.2"
}
}
And I updated the package.json of my cdk project to these scripts.
"build": "tsc && npm run build:webpack",
"build:webpack": "for file in ./src/*; do (cd $file && npm i && npm run build) & done",
"build:beta": "tsc && npm run build:webpack:beta",
"build:webpack:beta": "for file in ./src/*; do (cd $file && npm i && npm run build:dev) & done",
Notice that my file structure is as follows:
./
bin
lib
src
package.json
With src holding the source code for my project's lambdas.
I am not sure if you are familiar with webpack, but I have divided my webpack configuration in common, dev, prod.
A dev webpack configuration is specially useful for debugging because otherwise you lose line numbers among other useful information when something goes wrong on runtime.

How is ESLint integrated into Create React App?

When I run npx create-react-app ..., a bare-bone React project is being created for me.
When I then peek into package.json, there seems to be some evidence of ESLint to be present, as there is this:
"eslintConfig": {
"extends": "react-app"
},
However, whenever I install ESLint as a dev dependency and configure it -- as I usually do --, VS Code seems to pick it up.
In this case, VS Code does not seem to recognize that there is any kind of linter present/configured.
This is not super surprising, as ESLint is not a dependency of the React project I just generated -- at least not according to package.json.
When I try to run eslint . within the project's root directory, it says "command not found".
I tried to breathe life into this ESLint configuration by expanding it, so now I have this:
"eslintConfig": {
"extends": ["react-app", "eslint:recommended", "google"],
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "double"]
}
},
This changes nothing.
I manipulated the source code in a way that I know it violates the above configuration, yet, I have not been signaled any wrongdoing.
This leads me to a simple question:
Do projects generated by create-react-app come with some kind of ESLint configuration, and, if so, how do I enable and extend it correctly?
As I am being referred to the number one Google hit that comes up when searching "create react app eslint" -- which I have obviously read --, let me clarify what I mean:
ESLint is obviously integrated into Create React App in a different way than it would be if it had been manually added to the project using like so.
This is not only evident by the sheer number of people who post about their struggles of getting the two to work together.
This is also evident as...
...one cannot run the eslint command in the project root.
...ESLint does not seem to be a dependency within package.json.
...VS Code doesn't pick up that there is ESLint present.
...there is no .eslintrc.* file in the project root.
...etc.
So: How do I go about ESLint in the context of Create React App? For starters: How do I run it? How do I expand it? And why does VS Code not pick it up -- even though it usually notices the presence of ESLint?
Yes, create-react-app comes with eslint config.
How do I enable and extend it correctly?
You can check how to extend it here.
{
"eslintConfig": {
"extends": ["react-app", "shared-config"],
"rules": {
"additional-rule": "warn"
},
"overrides": [
{
"files": ["**/*.ts?(x)"],
"rules": {
"additional-typescript-only-rule": "warn"
}
}
]
}
}
How do I enable it?
You need to integrate it with your IDE.
How do I run it?
After integrating it, an eslint server will be running in the background and will enable linting for your IDE (sometimes restarting IDE required).
I checked all your claims after running npx create-react-app example:
...one cannot run the eslint command in the project root.
You can:
eslint is installed as part of the project dependency, just by running eslint globally (eslint [cmd]) you need to ensure it installed globally (not recommended).
...ESLint does not seem to be a dependency within package.json.
Why should it be? That's why you using a starter like CRA. It's an inner dependency, you don't need to worry about it, that's CRA's job.
...VS Code doesn't pick up that there is ESLint present.
It does, check the OUTPUT tab and look for ESLint to see the server's output.
...there is no .eslintrc.* file in the project root.
You get the default configuration from CRA (which is hidden from you for focusing on coding).
Add such file if you want to override it (you can also extend it, check the docs).
Its very useful to understand what eslint actually is and how we use it React development, check out related question "Do React hooks really have to start with โ€œuseโ€?".
To expand on the top comment's answer:
...ESLint does not seem to be a dependency within package.json.
Why should it be? That's why you using a starter like CRA. It's an inner dependency, you don't need to worry about it, that's CRA's job.
A project created with create-react-app will have react-scripts as a dependency.
react-scripts has eslint installed as a dependency, as seen in react-scripts package.json.
You can see if a package is installed (and where) by running npm ls <package> in your project root.
npm ls eslint shows:
โ””โ”€โ”ฌ react-scripts#4.0.3
โ””โ”€โ”€ eslint#7.21.0
This shows the dependency tree that we manually investigated by looking in GitHub at react-scripts.
So - a project made with create-react-app does come with eslint. As it is a dependency, not something globally installed, then it must be ran with a npm script.
This is why running eslint . in your terminal does not work, but using
"lint": "eslint .",
then npm run lint does. (though you may with to make the command eslint --ignore-path .gitignore . due to a current bug).
Similarly, the eslint configs are installed in react-scripts, then referenced in the default project output's own package.json.
Every Create React App depends on ESLint via react-scripts
I believe I have answered most of your questions in the Sections
below.
Here is a summary.
Do projects generated by create-react-app come with some kind of
ESLint configuration?
โ€“ Yes, ESLint gets installed and configured.
(Section 1 below.)
How do I enable and extend it correctly?
โ€“ It is already enabled. You expand it exactly as you already suggested
in the question, except that you don't need to change anything under
the extends attribute.
(Sections 1 & 2 below.)
ESLint is obviously integrated into Create React App in a different
way than it would be if it had been manually added to the project
using
[npm install eslint --save-dev and npm init #eslint/config ?]
โ€“ No, it's not.
Installing ESLint once again
(npm install eslint --save-dev) does add
ย  "devDependencies": {
ย  ย  "eslint": "^7.32.0"
ย  }
to package.json.
But that's all it does.
The practical implications are none, because "eslint": "^7.32.0" is
already installed as a dependency via react-scripts.
I advise against running npm init #eslint/config, which is
a command that creates a .eslintrc.* configuration file.
If you do run this command, consider moving all the contents of
.eslintrc.* to package.json under eslintConfig.
Then delete the problematic .eslintrc.* file.
It might save you a lot of pain.
1
(Sections 1 & 5 below.)
one cannot run the eslint command in the project root [?]
โ€“ Yes, you can!
It's npx eslint . --ext .js
(Section 4 below.)
ESLint does not seem to be a dependency within package.json [?]
โ€“ Yes, it is!
The dependency is indirect as react-scripts depends
on ESLint and on a lot of other packages.
(Section 1 below.)
VS Code doesn't pick up that there is ESLint present [?]
โ€“ Yes, it does! Run npx eslint . --ext .js.
If you get at least one warning or error, then you know you should see
it in VS Code as well.
(Section 3 below โ€“ check out the gotchas.)
there is no .eslintrc.* file in the project root.
โ€“ Be glad there isn't! And don't put one there either!
(Section 5 below.)
0. Prerequisites
In order to be able to answer your questions, I created an App :
2
npx create-react-app how-is-eslint-integrated-into-create-react-app
I then deleted all files in the src subdirectory, and inserted my own
versions of App.js, App.css, index.js, index.css, along with
a components subdirectory that contains a Button component.
In package.json I deleted a few irrelevant lines, such as
"version": "0.1.0",
and "private": true, and the production attribute
under browserslist.
The resulting package.json :
{
"name": "how-is-eslint-integrated-into-create-react-app",
"dependencies": {
"#testing-library/jest-dom": "^5.16.2",
"#testing-library/react": "^12.1.3",
"#testing-library/user-event": "^13.5.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"development": [
"last 1 chrome version"
]
}
}
When you wrote your question a little more than two years ago,
the eslintConfig attribute was
,
"eslintConfig": {
"extends": "react-app"
}
whereas nowadays, it's
,
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
}
I will assume that this change makes no difference for the issues and
questions you bring up
(unless someone proves me wrong).
Another difference over the past two years โ€“ apart from the obvious
changes in version numbering โ€“ is the added web-vitals attribute :
,
"web-vitals": "^2.1.4"
which is a package for measuring performance metrics in JavaScript.
3
Thus, web-vitals is irrelevant for your questions.
You can download the resulting
zip file containing all necessary project files.
Once downloaded โ€“ from the root of the project (directory Q59633005)
โ€“ run npm install.
Expect it to take anytime between 4 and 11 minutes to complete.
Next run npm start.
Expect your default web browser to open and
โ€“ after hitting F12 โ€“ display :
4
Now close the server from the terminal by hitting
Ctrl+C.
Take a look inside App.js. The contents are :
// App.js
import React, { useCallback, useState } from 'react';
import "./App.css";
import Button from "./components/UI/Button/Button"
function App(unUsedArgument) {
const [unUsedVariable, setShowParagraph] = useState(true);
const showParagraphFcn = useCallback(() => {
setShowParagraph((prevToggle) => !prevToggle);
},[]);
console.log("App RUNNING");
return (
<div className="app">
<h1>Hi there!</h1>
<Button onClick={showParagraphFcn}>A Button</Button>
</div>
);
}
export default App;
I now have project to help answer your questions.
1. ESLint in Visual Studio Code
VS Code does not seem to recognize that there is any kind of linter
present/configured.
This is not super surprising, as ESLint is not a dependency of the
React project I just generated -- at least not according to
package.json.
The npx create-react-app ... does indeed install ESLint.
ESLint is deeply buried in the dependency tree of the react-scripts
package.
The top node for ESLint in react-scripts is eslint-config-react-app.
5
Some basic configuration is also part of the deal.
So ESLint does work out of the box.
VS Code shows a warning for unUsedVariable on line 7 of App.js
(but for some reason not for unUsedArgument on line 6).
In VS Code, expect to see :
2. How to expand ESLint
How do I expand [ESLint in a Create React App]?
To expand ESLint, you need to add rules under eslintConfig in
package.json, exactly as you have already suggested in your
question.
To try your example, replace
,
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
}
with
,
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
],
"rules": {
"semi": [
"error",
"always"
],
"quotes": [
"error",
"double"
]
}
}
After restarting VS Code, it still shows the warning for
unUsedVariable on line 7, but now also an error on line 2 for having
single quotes instead of double quotes, and an error on line 4 for the
missing semicolon at the end of the line.
This shows that you have already correctly answered how to expand
Create React App.
For another example, consider looking at the
package.json | eslintConfig of this answer.
3. Some gotchas with VS Code
Still don't see the errors and warnings as in the screenshot
above?
It might not work, I know.
Three gotchas to check :
You must install the VS Code ESLint extension.
After you have made any changes to package.json, you must close
and restart VS Code.
Then wait at least 60-100 seconds (or even 2 minutes) before
you conclude it didn't work.
Add "eslint.nodePath": "C:\\Program Files\\nodejs", to
settings.json in VS Code.
4. A much faster way to check if ESLint works
For starters: How do I run it?
Answer:
6
npx eslint . --ext .js
The first four lines of the response:
C:\stackexchange\stackoverflow\linting\eslint\Q59633005\src\App.js
2:46 error Strings must use doublequote quotes
4:51 error Missing semicolon semi
7:10 warning 'unUsedVariable' is assigned a value but never used no-unused-vars
โ€“ In less than 10 seconds, you get the same information about errors
and warnings as in VS Code.
5. A word of warning
If you don't like hard-to-debug errors such as
Parsing error: The keyword 'import' is reserved
then don't use any .eslintrc.* files at all.
1
In my experience, you can put all ESLint configurations under
eslintConfig in package.json as described in Section 2 above.
โ€“ You won't need any .eslintrc.* files.
References
Every Create React App depends on ESLint via react-scripts
Long answer to Parsing error: The keyword 'import' is reserved
Short answer to Parsing error: The keyword 'import' is reserved
Zip file containing the needed project files
NPMGraph - Visualize NPM Module Dependencies
Post containing package.json โ€“ another eslintConfig example
VS Code ESLint extension
In VS Code, add "eslint.nodePath": "C:\\Program Files\\nodejs",
to settings.json
Parsing error: The keyword 'import' is reserved
1
If you want to know why, compare this long answer with
this short answer.
2 I'm on Windows 10, but I expect all the commands
provided here to work just as fine on both Linux and macOS โ€“ except
where otherwise stated.
3 You can find that out by running npm ll.
4 I use Google Chrome Version 98.0.4758.102, 64-bit.
Running on Windows 10.
5 I got this information from
NPMGraph - Visualize NPM Module Dependencies.
6 Alternatively, use the first line below if you are on
Microsoft Windows (backslashes).
Use the second line if you are on Linux or macOS (forward slashes).
node*modules\.bin\eslint . --ext .js
node*modules/.bin/eslint . --ext .js
your question makes perfect sense. I found that this works:
run ESLint in VS Code with 'npx eslint' (shows all the options) or also 'npx eslint .'
add a script to package.json "lint": "eslint ." and then use 'npm run lint'
I did not have a problem with integrating ESLint to VS Code. After installing VS Code extension for ESLint, I automatically see the warnings/errors in VS Code under Problems.

How can I incorporate JS libraries into my NPM build script?

My current site is build with html+css (scss) and using a NPM build script (see below). I now want to add a few JS libraries to my website (for example: lozad).
So far I've downloaded the dependencies for it. As I'm not familiar with JS, I don't understand the other steps I need to take. I tried following the documentation but it's not working so far.
I now assume that this is because my current NPM build script doesn't track JS, so any JS wouldn't be shown on my devserver. So maybe it did work, but just not in test?
Can anyone point me in the direction of what I need to do to make it working, and/or how to update my NPM script?
"scripts": {
"watch:sass": "node-sass sass/main.scss css/style.css -w",
"devserver": "live-server --browser=firefox",
"start": "npm-run-all --parallel devserver watch:sass",
"compile:sass": "node-sass sass/main.scss css/style.comp.css",
"concat:css": "concat -o css/style.concat.css css/icon-font.css css/style.comp.css",
"prefix:css": "postcss --use autoprefixer -b 'last 10 versions' css/style.concat.css -o css/style.prefix.css",
"compress:css": "node-sass css/style.prefix.css css/style.css --output-style compressed",
"build:css": "npm-run-all compile:sass concat:css prefix:css compress:css"
},
"devDependencies": {
"autoprefixer": "^9.6.0",
"concat": "^1.0.3",
"node-sass": "^4.12.0",
"npm-run-all": "^4.1.5",
"postcss-cli": "^6.1.2",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.6"
},
"dependencies": {
"aos": "^2.3.4",
"lozad": "^1.9.0",
}
}
You just need to give the relative path to the dependency and run the script like so:
"scripts": {
...
"lozad": "npm run ./node_modules/lozad/index.js --argument"
}
Note that this is only assumed data. The real path and file are probably called something else (Just look into the node:modules folder for lozad).
According to this article, you can also omit the path and the npm rum when there is a .bin folder for that dependency, but I have not tested that.
Edit
In case you meant on how to use the library locally.
You have to add the package to your dependencies (Like you did) and then call
npm install
in your project directory. It will install all your dependencies specified in package.json.
You can omit the manual "add dependency to file" step by simply calling:
npm install --save lozad
After that you can use it in your project like so:
// using ES6 modules
import lozad from 'lozad'
// using CommonJS modules
var lozad = require('lozad')
If you don't know which one to use, just try them - your IDE will tell you if something is wrong.
When you imported the library, you can use it like described at the Usage Description.

Categories

Resources