Using Sequelize CLI with the ESM package - node.js

Is there a way to execute Sequelize migrations with the ESM package? It requires the -r esm command line argument to be passed, but I don't seem to find that in their docs

I had the same issue and the way I got around it is by calling sequelize-cli from the node_modules folder.
In my package.json
{
"scripts": {
"migrate": "node --require esm ./node_modules/.bin/sequelize-cli db:migrate"
}
}
then if you run npm run migrate it should work with es6 imports.

Related

How can i use es6 modules in node.js

I'm trying to import express into my project using ES6 syntax, but it keeps giving me the error:
import express from "express";
SyntaxError: Unexpected identifier
I have done a bit of research and found where people were saying to add:
"type":"module"
to my package.json file, which I have done:
...
"description": "Shopping list to learn the MERN stack",
"type": "module",
"main": "server.js",
"scripts": {
"start": "node server.js",
"server": "nodemon server.js"
},
...
But I'm still getting the same issue. I would prefer to use the import ES6 syntax rather than this syntax.
const express = require('express')
Solution:
For me the best, easiest and most compatible way to resolve (dated to September 2019) was to:
npm install esm
ensure that the script is run by node with the -r esm option.
Simple as that.
The Node way:
(according to the ECMAScript Modules Documentation)
Other than the "type": "module" property into package.json NodeJS requires the scripts to be run via node --experimental-modules <your_script.js>.
Code into either .mjs or .js extension files will be treated with the support for new ES6. Renaming that I find pretty inconvenient.
Note: "type": "module" is particularly important for supporting .js files. Read the linked documentation.
The solution provided by NodeJS with the --experimental-modules flag didn't work for me in all cases. 🤷‍♂️
Adding the esm packages is more maintainable; and reliable. And can be easily/quickly removed once the ESM support won't be experimental anymore.
Offtopic tip:
If you want to run tests on your ES6 import/export code, I suggest to rely on a solid/flexible framework, like Mocha.
You can follow this instructions to run Mocha tests supporting ES6.
Trying with Jest I wasn't able to run test successfully. Apparently they don't want to directly support the experimental ES6 and suggest to transpile the code (thing that I hate).
References:
https://alxgbsn.co.uk/2019/02/22/testing-native-es-modules-mocha-esm/
https://timonweb.com/tutorials/how-to-enable-ecmascript-6-imports-in-nodejs/
https://nodejs.org/api/esm.html#esm_ecmascript_modules
If you try to run Node js app with ES6 syntax, you will encounter this kind of error
SyntaxError: Cannot use import statement outside a module
let's fix that
install three main packages
npm install --save-dev #babel/core #babel/preset-env #babel/node
npm install --save-dev nodemon
add .babelrc file with this
{ "presets": ["#babel/preset-env"] }
and this in package.json
"start": "nodemon --exec babel-node app.js"
Ok, so, after doing even more research on the ES6 way, this is what worked for me. It's a combination of an answer above and the following:
package.json
node --experimental-modules server.mjs
server.mjs
import dotenv from 'dotenv'
dotenv.config()
const db = process.env.MONGO_URI
I've created a nodejs boilerplate supporting es6 module.
https://github.com/jasonjin220/es6-express-rest-api-boilerplate
You need Babel transpiler to do this, as Node.js doesn't support es6.
First add these packages to your project :
npm install --save-dev babel-cli babel-preset-es2015 rimraf
Then, create a .babelrc file , this is used by Babel transpiler to know some information during transpilation.
touch .babelrc
Then, add this line to .babelrc :
{
"presets": ["es2015"]
}
This tells your Babel to use es6 presets as per 2015 standard.
Then, modify the package.json and tell it to use transpiler.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rimraf dist/ && babel ./ --out-dir dist/ --ignore ./node_modules,./.babelrc,./package.json,./npm-debug.log --copy-files",
"start": "npm run build && node dist/index.js"
},
You have to add the following to script section, this line tells when you run npm run start , the transpiler will first convert the es6 syntax to minmal JavaScript one, later that is used.
Check your dependencies :
"dependencies": {
"express": "^4.15.2",
"morgan": "^1.8.1",
"rimraf": "^2.6.1"
}
And Dev dependencies :
"devDependencies": {
"babel-cli": "^6.24.0",
"babel-preset-es2015": "^6.24.0"
}
This should work, comment if there is any issue.
You need to use Babel,
npm install --save-dev #babel/plugin-proposal-class-properties
then for usage create a .babelrc file if you don't have it, with options:
{"plugins": ["#babel/plugin-proposal-class-properties"]}
then ad devDependencies in package.json
"#babel/plugin-proposal-class-properties": "^7.5.5",
that should do the job.

Errors installing jest in console [duplicate]

I have a test file like so: (I am using create-react-app)
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/Calculator';
import { getAction, getResult } from './actions/'
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
it('renders without crashing', () => {
const wrapper = shallow(<App />)
expect(toJson(wrapper)).toMatchSnapshot();
});
it('displays the choosen operator', () => {
const action = {
type: 'GET_ACTION',
operator: '+'
};
expect(getAction("+")).toEqual(action)
})
it('displays the typed digit', () => {
const action = {
type: 'GET_RESULT',
n: 3
};
expect(getResult(3)).toEqual(action);
})
it('checks that the clickevent for getNumber is called',() => {
const clickEvent = jest.fn();
const p = shallow(<p data-n="1" onClick={clickEvent}>1</p>)
p.simulate('click')
expect(clickEvent).toBeCalled();
})
and a package.json:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
// "test": "react-scripts test --env=jsdom",
"test": "jest",
"eject": "react-scripts eject"
},
"devDependencies": {
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.3",
"jest": "^22.4.3"
}
}
when I run jest --updateSnapshot I get:
command not found: jest
but jest is installed.
Jest is installed, but is likely in your ./node_modules/.bin directory. You can append that to your command ./node_modules/.bin/jest --updateSnapshot. Since you already have jest as a scripts command in your package.json you can also run it with npm test -- --updateSnapshot. npm automatically adds ./node_modules/.bin to your path.
update: Newer versions of yarn will resolve node module bin scripts, so you can also just run yarn jest {cmd} and it should work.
I ran into similar issue. I fixed it by installing jest globally.
npm install -g jest
You need to run it this way :
./node_modules/.bin/jest
or run npm test
Install the Jest command-line interface (Jest CLI):
npm install --save-dev jest-cli
Then run the jest command. Working for me in a linux instance by docker on Windows 10.
I was getting zsh: command not found: jest after installing jest and trying to use the command jest. The solution that worked for me was running npx jest
A way to solve the error is to use the "npx" command.
npx jest --version
npx jest --init
In my case, npm didn't install the jest command for some reason.
To fix this:
I deleted the node_modules/jest directory
Re-ran npm install and got the jest command installed.
try using the command
npx jest <folder>
I ran into the same problem. I tried multiple solutions and this worked.
I also have jest CLI installed
you can install it by using this command in your shell
npm install --save-dev jest-cli
just use command
npm test or npm t
Removing node_modules and running npm install again fixed this for me
Also the "new" npm ci command can fix this as it deletes (or clears) node modules and performs a clean install each time, plus it's faster compared to manually deleting node_modules and re-installing
My situation was caused by my git pipeline. I wasn't caching node_modules nor was I caching untracked files.
Ultimately I added
cache:
# untracked: true
key:
files:
- package-lock.json
paths:
- node_modules
to my pipeline .yml and violá
Note
you can either use path OR untracked, find out more about each to see what works best for you
Just reload your bash config file after install jest:
source ~/.bashrc # on linux ?
source ~/.bash_profile # on macOs
Jest will be not recognized but executed with npx jest automatically
I use yarn. Adding jest and jest-cli to node_modules did not make any difference with my attempts to run tests like jest mytest.test.js. In addition to mentioned steps, the following helped to get it running:
yarn jest mytest.test.js
you can run ln -s ./node_modules/.bin/jest jest
and then run jest --init it will work. Or you can install jest cli with npm install --save-dev jest-cli and then run jest --init it will also work.
In my case, I was trying to install jest with yarn on a pipeline to run tests and since I had jest installed as a devDependency it wasn't installing on yarn install.
I found this bug on GitHub https://github.com/yarnpkg/yarn/issues/2739 that it seems that Yarn will not install devDependencies when NODE_ENV=production.
I just needed to change the NODE_ENV and after that, it was working, otherwise, run it like this:
yarn install --production=false
Faced the same issue. But it was due to the wrong node version. If you use the latest jest v29, you need Node version 14 or higher.
You can run the test using npx jest [parameters]. npx is the package runner. It will help you execute a locally installed package.
Had the same issue and was able to solve it by running npm install
Alternatively, just add jest module to package.json dependencies.
{
"dependencies": {
...
"jest": "^29.3.1",
...
}
}

How do I globally install a node-cli tool with es6 import support?

I am creating a simple project-generator tool and I am using es6 imports in my main index.js file. I have a babel-node installed with a .babelrc at the root of my project.
To install the tool globally I have this in my package.json:
"bin": {
"generate": "./node_modules/.bin/babel-node ./index.js"
},
When I run npm link or npm install -g at the root of my project, I get the error:
ENOENT: no such file or directory, chmod '/usr/local/lib/node_modules/node-project-generator/node_modules/.bin/babel-node ./index.js'
I have also tried:
"bin": {
"generate": "babel-node ./index.js"
},
and
"bin": {
"generate": "npx babel-node ./index.js"
},
This tool is working just fine in the context of my project. So how do I add es6 support to install it globally?
Have you added babel-node as a dependency to your package?
Anyway, the more proper way of doing it is to compile your program with babel into some dist directory in advance so that it can be run without any additional pre-processor.
"bin": {
"generate": "./dist/index.js"
}
Less problematic and faster command execution.

How do I deploy my Typescript Node.js app to Heroku?

When testing locally I was previously running:
"build-live": "nodemon --exec ./node_modules/.bin/ts-node -r dotenv/config -- ./index.ts"
I then figured my Procfile should be something like:
web: ./node_modules/.bin/ts-node -- ./index.ts
But it says module 'typescript' not found, even when it is in package.json. I read in a few places that ts-node is not the way to go to deploy to Heroku, so I am not sure what to do.
UPDATE: I think I am supposed to compile it, so I tried:
web: ./node_modules/.bin/tsc --module commonjs --allowJs --outDir build/ --sourceMap --target es6 index.ts && node build/index.js
This succeeds, however when actually running it, a bunch of the libs I'm using get "Cannot find module '...'".
Alternatively you can have the TypeScript compile as a postinstall hook and run node build/index.js as the only Procfile command:
Your package.json should contain a postinstall hint that gets executed after npm install and before the node process launches:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
You can then leave your Procfile as is:
web: npm start
This 'build on deploy' approach is documented by Heroku here.
The command you've given Heroku is to launch the web "process" by compiling index.ts and dependencies and starting node at index.js. Depending on how things are timed, index.js might or might not exist at the time node starts.
You need to already have your sources compiled by the time you want to start your app. For example, web should just be web: node index.js or similar.
Each build process is different, so you need to figure that out for your own setup. But, suppose you have a classical setup where you push to git and then Heroku picks up that change and updates the app with the new slug. You could just compile things locally and include index.js and any other build output in the repository, for it to be available in the slug for Heroku to use.
A better approach is to use a build server which has an integration with Heroku. After you do the build there, configure it to send the build results to Heroku. Travis has a straighforward setup like this. This way you don't need to include build outputs in your repository, which is considered an anti-pattern.
On a sidenode, try using a tsconfig.json to keep the tsc configuration. It will save you from having to write such long command lines all over the place.
Fabian said that we could do something like:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
As of me writing this, I tested this and can state: postinstall is not required since build script is ran by Heroku. If you want to do it without build script, then you can use heroku-postbuild which will run after dependencies are installed there you run tsc to compile.
My problem was about missing Typescript npm modules. The Typescript compiler tsc was not found when deployed the app to Heroku.
The Heroku deploy process (rightly) does not install development dependencies, in my case the Typescript module was part of devDependencies and thus the tsc command was not running on the Heroku platform.
Solution 1
Add typescript to dependencies: npm i typescript -s
Solution 2
Open Heroku console:
Select console type:
Run the command npm i typescript && npm run tsc
Install typescript as a dev dependency (cf. https://www.typescriptlang.org/download). Once built, your app does not need typescript anymore!
npm install -D typescript
Then in your package.json:
{
"main": "index.js", // <- file will be generated at build time with `tsc`
"scripts": {
"build": "tsc",
"start": "node ."
"start:dev": "ts-node index.ts" // idem, install ts-node as a dev dependency
}
}
The key point here is "build": "tsc".
Why?
Heroku does install all dependencies during build and remove the dev dependencies before the app is deployed (source here).
Node.js deployments will automatically execute an app’s build script during build (since March 11. 2019 source here)
In package.json
"scripts": {
"tsc": "./node_modules/typescript/bin/tsc",
"postinstall": "npm run tsc"
},
Works for me for Heroku deployment.
Installing typescript npm install -D typescript and writing tsc in the build script "build": "tsc", does not work for me. Also, try to run npm i typescript && npm run tsc in the Heroku console which also does not work.
In my case, I remove some dependencies from "devDependencies" to "dependencies", so it goes like this:
"dependencies": {
// The other dependencies goes here, I don't touch them.
// But all TS dependencies I remove to here.
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.2.3",
"ts-loader": "^8.0.18"
},

How does "npm" run "npm test"?

I always thought that npm test command just launches what I would write in package.json inside scripts: { test: ...} section. But I have this weird bug when it doesn't work.
So, I have this piece of config in package.json
"scripts": {
"start": "node index.js",
"test": "mocha tests/spec.js"
}
When I try to run tests I type npm test in terminal and had this error:
module.js:340
throw err;
^
Error: Cannot find module 'commander'
But everything is OK when I type just mocha tests/spec.js. Any ideas why is that?
UPDATE:
I've tried to install commander and I had an error Cannot find module 'glob'. After installing glob I have
Error: Cannot find module '../'**
But actually question is why do I have these errors and why is everything OK when running mocha tests/spec.js?
You may have two versions of mocha installed: one globally (npm install -g mocha) and one locally, which appears to be broken.
When you run a script through npm, either as npm run-script <name> or with a defined shortcut like npm test or npm start, your current package directory's bin directory is placed at the front of your path. For your package that's probably ./node_modules/.bin/, which contains a link to your package's mocha executable script.
You can probably fix this by removing the local mocha and reinstalling it with --save-dev:
rm -rf node_modules/mocha
npm install --save-dev mocha
That should get you a working local copy of mocha with all its dependencies (commander etc.) installed.

Resources