Razzle: Usage of babel-register

Created on 9 Apr 2016  路  17Comments  路  Source: jaredpalmer/razzle

Hi,

Thanks for the great repo!
I have a concern about the usage of babel-register on the server.
According to babel docs, it should not be used in production.

Note that this is not meant for production use. It's considered bad practice to deploy code that gets compiled this way. It is far better to compile ahead of time before deploying.

Is there a plan to tackle this issue?

Most helpful comment

Okay, got this issue fixed in some way.

We need to add this in razzle.config.

module.exports = {
  modify: (config, { target, dev }) => {
    if(target === "node") {
      config = {
        ...config,
        externals: []
      }
    }
    return config;
  }
}

In order for this work in your CI pipeline, you need to make the process.env.CI to false.

Because, if CI environment variable is true, warnings are treated as errors and your build will fail. Why is this you ask ? Because of express dependency issue

./node_modules/express/lib/view.js
Critical dependency: the request of a dependency is an expression

All 17 comments

We could compile the whole src folder into build? Did a quick test and here's what I've come up with:

"start:prod": "npm run build:server && npm run build && NODE_ENV=production node ./build/server/server.js",
"build:server": "babel src --out-dir build",

I've replaced the npm scripts and it seems to work. I'm sure there are better solutions though.

Will need to use webpack on the server

Currently trying this out http://jlongster.com/Backend-Apps-with-Webpack--Part-I

Will do a PR when I get it working. 馃憤

Problem is that there is no HMR on the server, even with jlongster's approach. 馃槮

How about if it was limited to production only?

It would look something like this:

// webpack.server.prod.config.js

var webpack = require('webpack')
var fs =  require('fs')
var path = require('path')

module.exports = {
  target: 'node',

  devtool: 'inline-source-map',

  entry: path.join(__dirname, 'app.js'),

  output: {
    filename: path.join(__dirname, 'app.bundle.js')
  },

  // keep node_module paths out of the bundle keep size down
  externals: getExternals(),

  node: {
    __filename: true,
    __dirname: true
  },

  module: {
    loaders: [
      { test: /\.js$/, loader: 'babel-loader' }  // handwaiving here
    ]
  },

  plugins: [
    new webpack.BannerPlugin(
      'require("source-map-support").install();',
      { raw: true, entryOnly: false }
    )
  ]
}

function getExternals() {
  const nodeModules = fs.readdirSync(path.resolve(__dirname, 'node_modules'))
  return nodeModules.reduce((ext, mod) => {
    ext[mod] = 'commonjs ' + mod
    return ext
  }, {})
}

Thanks for the quick response! So basically after using this config, we need to change start:prod script to use app.bundle.js right?

Another question about running in production, currently start:prod command uses node to run the server.
Shouldn't we use something like PM2 to run the server on production?
So it will auto-restart on code changes and scale to all cores?

Pm2 is a lot of overhead. We use Throng in production. But yes we can make that change.

Hi guys,
It seems like we still need the node_modules in production as well? Deploying only the /build folder throw an error babel related, so I'm wondering if this issue isn't related. Did anyone figured out something similar?

When doing node ./build/server.js using only the /build folder:
Error: Cannot find module 'babel-runtime/core-js/json/stringify'

Thanks!

Edit: reformulate my question: Why do we still need the node_modules in production even if all the code is bundled by Webpack? Shouldn't everything needed for production be contained within the /build folder?

You don鈥檛 need Node modules in prod

Hi Jared,
Thanks for your answer :)

That's what I expected as well! So I tested with a fresh install, with examples/basic and followed this process:

  • cd examples/basic
  • npm install
  • npm run build
  • rm -rf node_modules
  • npm run start:prod

and then it fails with:
Error: Cannot find module 'express'

Should I open a new issue or am I doing something wrong?

For posterity:
From what I understand of the Webpack config for the backend, it uses webpack-node-externals as seen in this line so the node_modules are not bundled with the backend bundle. Which means the node_modules are required on production and have to be deployed alongside the /build folder.

Hi @Grsmto,
Can you resolve the problem? To build razzle app with include node_modules?
For me it's not good to copy all files from catalog node_modules to production.

Hi @krystianjj,
I had to copy the node_modules folder to the production server or build the app directly on the production server. unfortunately I didn't find a way to deploy only the /build folder.

Thank you for quick response @Grsmto
I do the same - copy package.json to production server run npm install and I have build folder with node_modules.
Maybe @jaredpalmer can add fix in future for this, or this is good solution to copy node_modules to the server.

Anyone got this working, I don't want to take the node_modules along to the production server after creating the bundle.

Okay, got this issue fixed in some way.

We need to add this in razzle.config.

module.exports = {
  modify: (config, { target, dev }) => {
    if(target === "node") {
      config = {
        ...config,
        externals: []
      }
    }
    return config;
  }
}

In order for this work in your CI pipeline, you need to make the process.env.CI to false.

Because, if CI environment variable is true, warnings are treated as errors and your build will fail. Why is this you ask ? Because of express dependency issue

./node_modules/express/lib/view.js
Critical dependency: the request of a dependency is an expression

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Jayphen picture Jayphen  路  4Comments

howardya picture howardya  路  5Comments

sebmor picture sebmor  路  4Comments

kkarkos picture kkarkos  路  3Comments

gabimor picture gabimor  路  3Comments