Tools: Node 5.4.0, Express 4.13.4, React 0.14.7, webpack 1.12.14
Problem:
Both Node and Babel have had major updates over the past couple months and
so I'm having trouble straightening out how to configure Node to parse Isomorphic components written in ES6 syntax.
Error:
Client-side rendering(bundled by webpack) is working, but during server-side rendering I get this issue
import MyComponent from './components/
^^^^^^
SyntaxError: Unexpected token import
Background - things I did:
1) Updated Babel
I figured that the newest versions of Node would natively been to parse ES6 syntax for importing, but since it didn't I figured updating babel to
6.x would do the trick.
So I updated babel-loader 6.2.4 and other modules that depend on it.
npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
2) Created a .babelrc file
I didn't know exactly what this file was for but since many people used it and mentioned it I thought I'd throw it in there.
.babelrc
{
"presets":["react","es2015"]
}
3) Updated Webpack Queries
I figure this only affects the client-side rendering but I'll mention that I did update
by adding in the "presets".
webpack.config.js
module.exports = {
entry: "./js/app.js",
output: {
filename: "./public/js/bundle.js"
},
debug: true,
devtool: "source-map",
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query:{
presets:['react','es2015']
}
}
]
},
};
Just to incase it helps:
Here is my list of my dependencies.
{
"name": "My App",
"version": "0.0.1",
"description": "Iso React Components",
"main": "app.js",
"dependencies": {
"classnames": "^2.1.3",
"express": "^4.13.3",
"express-handlebars": "~1.1.0",
"flux": "^2.0.0",
"history": "^1.13.0",
"html-webpack-plugin": "^2.9.0",
"keymirror": "~0.1.0",
"mongodb": "^2.1.3",
"node-jsx": "~0.12.4",
"object-assign": "^1.0.0",
"react": "^0.14.0",
"react-dom": "^0.14.0",
"react-router": "^2.0.0",
"react-scrollbar": "0.3.1",
"reactify": "^1.1.1"
},
"devDependencies": {
"babel-core": "^6.6.0",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"envify": "^3.0.0",
"jest-cli": "^0.4.3",
"node-libs-browser": "^0.5.2",
"uglify-js": "~2.4.15",
"webpack": "^1.12.1"
}
}
Question:
Once I switched out all the "import" syntax to Node require statements I was able to render server-side successfully. But I really don't like the idea of avoiding ES6 to make the React code Node/Browser compatible. What am I missing?
Take a look at Webpack Isomorphic Tools. It's a helper module you can add to your webpack config so that you can do ES6 imports or regular old requires in node and it'll do some magic and the require will resolve successfully.
Essentially you make an isomorphic config (which is detailed on the site) and then using the isomorphic webpack plugin, you can use it to render your assets (javascript, styles, etc) client side.
Edit: A word of caution of some bugs you may run into: In node, things like the window object don't exist so if any of your node modules use it, it will throw an exception when you try to render that particular library on the server. Just shim the window object and anything else you need.
Babel require hook could help node.js parse ES6 syntax automatically while require files.
Just run command
npm install babel-register --save
And add the following to the first line of your entry file
require("babel-register");
Related
this is question is basically a variant of dependencies vs. devDependencies, I am looking through some source code these days, most of monorepo project will have a eslint-config to do lint
what confuses me is that they all put the eslint-plugin into dependencies not devDependencies
for example, a eslint config package called eslint-config, here's package.json
"dependencies": {
"#typescript-eslint/eslint-plugin": "^5.15.0",
"#typescript-eslint/parser": "^5.15.0",
"eslint-config-standard": "17.0.0-1",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-html": "^6.2.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsonc": "^2.2.1",
"eslint-plugin-n": "^15.0.1",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-unicorn": "^41.0.1",
"eslint-plugin-vue": "^8.5.0",
"eslint-plugin-yml": "^0.14.0",
"jsonc-eslint-parser": "^2.1.0",
"yaml-eslint-parser": "^0.5.0"
},
"devDependencies": {
"eslint": "^8.11.0"
},
we of course use it by npm i eslint-config -D, so I wonder if the eslint config get removed after bundled(I think it's 100% get removed), but I want to know the behand philosophy
According to the npm and yarn documentation, in addition to another answer with a similar question, devDependencies do not impact the bundle size as they are utilized in development mode.
Two related GitHub issue comments discuss the reasoning behind your question, specifically dependencies included at runtime:
https://github.com/facebook/create-react-app/issues/3209#issuecomment-336602578
https://github.com/typescript-eslint/typescript-eslint/issues/770#issuecomment-516056543
on-rest my project was working great untill I delete my node_modules file and try to re-install npm package.
I am getting this error
./node_modules/react-event-listener/dist/react-event-listener.cjs.js
Module not found: Can't resolve '#babel/runtime/helpers/builtin/classCallCheck' in '/Users/suatkarabacak/Desktop/demarkedashboard/node_modules/react-event-listener/dist'
My package.json is looking like this.
{
"name": "demo",
"version": "0.1.0",
"private": true,
"dependencies": {
"admin-on-rest": "^1.4.1",
"aor-dependent-input": "^1.2.0",
"aor-parseserver-client": "0.3.0",
"aor-rich-text-input": "^1.0.1",
"babel-runtime": "^6.26.0",
"parse": "^1.11.1",
"parse-react": "^0.5.2",
"prop-types": "^15.6.2",
"react": "^15.6.2",
"react-dom": "^15.6.2",
"react-image-lightbox": "^4.6.0",
"react-images": "^0.5.19"
},
"devDependencies": {
"#babel/runtime": "^7.0.0-beta.56",
"aor-color-input": "^1.2.1",
"babel-polyfill": "^6.23.0",
"react-scripts": "^1.1.4"
},
"homepage": "demo.html",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
There is no builtin folder.
What could be the problem ?
Since Babel 7.x is still a beta version, there was a breaking change in beta.56, which was released yesterday.
"#babel/runtime": "^7.0.0-beta.56",
If you're using a beta version of something, it is dangerous to use ^ in your version number, because that means it will accept any recent version, whether or not it is actually compatible with previous beta versions.
Since react-scripts uses https://github.com/facebook/create-react-app/blob/1407287839f94151cec729bd89441d4eee7d9dd3/packages/babel-preset-react-app/package.json#L28
"#babel/plugin-transform-runtime": "7.0.0-beta.46",
Your should likely have
"#babel/runtime": "7.0.0-beta.46",
in your own package.json to match.
In my case the problem was in relative paths and complex project structure, so that I had to specify exact location of my node_modules directory:
module.exports = {
resolve: {
modules: [
path.resolve(__dirname, "node_modules")
],
...
In case you are running into this because of your dependency on material-ui:
Looks like material-ui updated its package.json to reference '7.0.0-beta.42' instead of '^7.0.0-beta.42'
See Issue: 12409
If you want to use the 7.0.0-beta.56 version, the easiest solution is to create builtin/ folder manually inside helpers/ folder then, move or copy the contents of helpers folder inside helpers/builtin/ and you will not see this error message anymore.
In case you do have material ui in there, make sure you've installed all that you're importing like /icons,/core.
I followed everything you recommended me to make the Babel 7 work with the Jest.
I installed the #babel/core and babel-core. Still It does not work.
{
"devDependencies": {
"#babel/cli": "^7.0.0-beta.51",
"#babel/core": "^7.0.0-beta.51",
"#babel/node": "^7.0.0-beta.51",
"#babel/plugin-transform-modules-commonjs": "^7.0.0-beta.51",
"#babel/preset-flow": "^7.0.0-beta.51",
"babel-core": "^7.0.0-beta.51",
"jest-cli": "^23.1.0"
}
}
After yarn jest
yarn run v1.9.0-20180612.1255
$ /Users/m/Desktop/k/node_modules/.bin/jest
FAIL packages/services/src/Client/__tests__/Client.js
- Test suite failed to run
Requires Babel "^7.0.0-0", but was loaded with "6.26.3". If you are sure you have a compatible version of #babel/core, it is likely that something in your build process is loading the wrong version. Inspect the stack trace of this error to look for the first entry that doesn't mention "#babel/core" or "babel-core" to see what is calling Babel.
at throwVersionError (node_modules/#babel/helper-plugin-utils/lib/index.js:65:11)
at Object.assertVersion (node_modules/#babel/helper-plugin-utils/lib/index.js:13:11)
at _default (node_modules/#babel/plugin-transform-modules-commonjs/lib/index.js:51:7)
at node_modules/#babel/helper-plugin-utils/lib/index.js:19:12
at Array.map (<anonymous>)
Saw your question on the Jest GitHub issues -- I think it was you, but I solved it on my end by going through the create-react-app repo and seeing how they integrated Jest. Specifically, the packages/react-scripts/package.json file has what you need.
"#babel/core": "7.0.0-beta.46",
"#babel/runtime": "7.0.0-beta.46",
"autoprefixer": "8.5.0",
+ "babel-core": "7.0.0-bridge.0",
"babel-eslint": "8.2.3",
"babel-jest": "22.4.3",
Add the line with the +, or change what version you have and you should be good.
Even though the Jest page says it includes babel-jest I found that adding it to my project fixes the problem.
yarn add --dev babel-jest babel-core#^7.0.0-bridge.0 regenerator-runtime
https://jestjs.io/docs/zh-Hans/getting-started
OK, I have an express app which is throwing this error at launch when deployed to Heroku. The app compiles and runs fine locally:
Cannot find module 'mongodb'
This app was running until I redeployed it yesterday ... here is my package.json which was unchanged
{
"name": "fitness-tracker",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"promise": "~6.0.1",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"mongodb-core": "*",
"mongoskin": "~2.0.0",
"express-handlebars": "~1.1.0",
"moment": "~2.0.0",
"moment-timezone": "^0.3.1",
"q": "~1.0.1",
"compass": "~0.1.0",
"apm": "*"
},
"devDependencies": {
"moment-timezone": "^0.3.1"
}
Ideas?
So the issue was package's resolution based on node version. Since NodeJS is rapidly evolving, it's a good practice to include engines specification in your package.json.
When doing automatic deployments on various cloud providers, this helps them to use only specified node & npm version. This was all the packages that get fetches are built for that node version hence less chances of app to misbehave.
Read more: https://docs.npmjs.com/files/package.json#engines
Also always worth a try: disable the Heroku build cache to recreate the node_modules directory.
In the Heroku CLI write:
$ heroku config:set NODE_MODULES_CACHE=false
$ git commit -am 'disable node_modules cache' --allow-empty
$ git push heroku master
As described here.
noob question regarding Node and npm: I have a package.json file with a list of dependancies that I want to install with npm install. When I run the command, nothing happens, I don't even receive an error, nothing at all :(
But if I try to install a single package from the list, it works perfectly...
I haven't created the package.json myself, so I am not sure what the "proxyURL" thing does...
{
"name": "dss",
"version": "0.0.0",
"repository": {
"type": "git",
"url": "*urlofmyrepo*"
},
"dependencies": {
"bower": "^1.7.7",
"cssmin": "^0.4.3",
"gulp": "^3.9.0",
"gulp-batch": "^1.0.5",
"gulp-concat": "^2.6.0",
"gulp-if": "^2.0.0",
"gulp-jshint": "^2.0.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^2.2.0",
"gulp-sourcemaps": "^1.6.0",
"gulp-strip-debug": "^1.1.0",
"gulp-uglify": "^1.5.1",
"gulp-util": "^3.0.7",
"gulp-watch": "^4.3.5",
"jshint": "^2.9.1",
"lodash": "^4.2.1",
"minimatch": "^3.0.0",
"sass": "^0.5.0",
"uglifyjs": "^2.4.10",
"underscore": "^1.8.3",
"yuglify": "^0.1.4"
},
"private": true,
"APIMethod": "stub",
"proxyURL": "http://localhost:8000",
"devDependencies": {}
}
Any clue?
Thank you
Rename/remove your package.json file.
Create a new package file by running:
npm init
Option A: Copy the dependencies you need into the newly created package.json.
Option B: Install the packages and use --save to add the packages to the package.json file.
Run npm install to install the dependencies.
just ran into this.
in my case the answer was environment variable NODE_ENV was set to 'production'
I haven't looked it up but when I changed it to something else, it started working.
I was testing this environment variable for something else and didn't realize it had this effect also.
For me it was a bad version value. Changing from 3.0 to 3.0.0 results in proper installation. 3.0 generates a warning, but fails to do the installation (ie it should be an error).