Skip to content

Part 7: Node and Webpack

KYY edited this page Aug 14, 2018 · 1 revision

Q: What are these exports, module.exports and export, export default?

  • for node: exports and module.exports
  • for es6: export, export default, and import
  • for both node and es6: require

Node.js treats each file as a separate module (see official docs), and different files/modules do not share the namespace. Each file/module has an "API" for access called module.exports. module.exports is an object {}, and exports provides a way to write into that object. For example, exports.name = 1; will modify module.exports to be {name:1}.

In ES6 JS, export and export default are the equivalent to Node's exports (see MDN docs):

There are two different types of export, named and default. You can have multiple named exports per module but only one default export.

Named export need to specify the same name during import, but default export can be imported under any name.

let k; export default k = 12; // in file test.js

import m from './test' // note that we have the freedom to use import m instead of import k, because k was default export

console.log(m);        // will log 12

require() works for both Node and ES6. In Node, require() is linked to the module.exports object.

Q: How do the package.json's scripts work with react-scripts?

This project is bootstrapped with Facebook's Create-React-App. And react-scripts is a key package for create-react-app. It is the portal for any customized configuration setup. The scripts that react-scripts run are specified in /node_modules/react-scripts/scripts/.

So when you run scripts in the package.json:

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    ...
    }

you are asking react-scripts to run the scripts like /node_modules/react-scripts/scripts/start.js or /node_modules/react-scripts/scripts/build.js to execute the scripts with node:

$ node ./node_modules/react-scripts/scripts/start.js
# = npm run start
$ node ./node_modules/react-scripts/scripts/build.js
# = npm run build

# npm run = npm run-script
...

Inside the scripts from react-scripts, these tasks have been taken care of:

  • set up a webpack-dev-server
  • set up an http server based on express
  • ESlint and babel etc...

The npm scripts syntax are compatible with bash syntax

  "scripts": {
    "script1": "echo npm script works in bash",
    "script2": "echo msg1 && echo msg2"
  }

And the output in bash will be:

$ npm run script1
> testnpmscript@1.0.0 script1 /testNPMScript
> echo npm script works in bash

npm script works in bash

$ npm run script2

> testnpmscript@1.0.0 script2 /testNPMScript
> echo msg1 && echo msg2

msg1
msg2

Q: What is the CI=true doing in the package.json's scripts?

process.env is the the global environment setting as read by Node. You can modify or create any environment values to the process.env by:

$ ALSET="awesome" node
> process.env.ALSET
'awesome'

So running the npm script "test": "CI=true react-scripts test --env=jsdom" is equivalent to:

$ CI=true node ./node_modules/react-scripts/scripts/test.js --env=jsdom

And the test.js specifies the logic for process.env.CI:

let argv = process.argv.slice(2);

// Watch unless on CI or in coverage mode
if (!process.env.CI && argv.indexOf('--coverage') < 0) {
  argv.push('--watch');
}

Q: How does the npm start automatically open my browser with a port 3000?

As specified in the package.json's scripts: "start": "react-scripts start", the shell will look for \node_modules\react-scripts\scripts directory's start.js and run with #!/usr/bin/env node:

const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; // here sets the port
const HOST = process.env.HOST || '0.0.0.0';
...
    const devServer = new WebpackDevServer(compiler, serverConfig);
    // Launch WebpackDevServer.
    devServer.listen(port, HOST, err => {
    ...
      openBrowser(urls.localUrlForBrowser); // here opens the browser
    });

Q: Where are the webpack configs for the app?

Since we choose not to eject this creat-react-app, we rely on the react-scripts to take care of the webpack configurations in /node_modules/react-scripts/config:

/node_modules/react-scripts/config/
├── env.js
├── jest
│   ├── babelTransform.js
│   ├── cssTransform.js
│   └── fileTransform.js
├── paths.js
├── polyfills.js
├── webpack.config.dev.js
├── webpack.config.prod.js
└── webpackDevServer.config.js