DEV Community

Masashi Hirano
Masashi Hirano

Posted on • Updated on

0cjs! Webpack4 tutorial: Building React app without config file.

On January, webpack4 was pre-released as beta.0.
On February 25, webpack4 was released 🎉
Webpack4 doesn't need a config file by default!
It made me excited and I tried to build My React app without webpack config.

About webpack4

Please refer to the links below.

Other tools

  • babel-preset-env
  • babel-preset-react
  • flow

My webpack config

const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    'index': [
      path.resolve(__dirname, 'src/index.js')
    ]
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'public'),
    publicPath: '/',
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    }),
    new webpack.optimize.UglifyJsPlugin(),
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader',
      },
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};

Enter fullscreen mode Exit fullscreen mode

How to use webpack4

Install

You have to install webpack 4 and webpack-cli.
From webpack 4, webpack-cli is necessary to execute webpack on command line.

npm install --save-dev webpack webpack-cli
Enter fullscreen mode Exit fullscreen mode

Build without config

module-bind

First, I executed webpack with no config and no options.
Error occurred.

Module parse failed: Unexpected token (15:6)
You may need an appropriate loader to handle this file type.
|   render() {
|     return (
|       <div>
Enter fullscreen mode Exit fullscreen mode

Above error means that babel is invalid and webpack doesn't analyze jsx syntax.
With config, below code solves this error.

module: {
  rules: [
    {
      test: /\.(js|jsx)$/,
      use: 'babel-loader',
    },
  ]
},
Enter fullscreen mode Exit fullscreen mode

if you want to use babel-loader, you need to use --module-bind options.
usage: --module-bind {extension}={loader-name}

webpack --module-bind 'js=babel-loader' --module-bind 'jsx=babel-loader'
Enter fullscreen mode Exit fullscreen mode

resolve-extensions

Though --module-bind option is valid, other error occurred.

Module not found: Error: Can't resolve './Foo' in '/path/to/src'
Enter fullscreen mode Exit fullscreen mode

This error means that import modules failed,
The reason why this error occurred is that I've omitted extensions like below code.

import Foo from 'components/Foo'
Enter fullscreen mode Exit fullscreen mode

With config, below soloves this error.

resolve: {
  extensions: ['.js', '.jsx'],
},
Enter fullscreen mode Exit fullscreen mode

Webpack4 has --resolve-extensions cli-option.
Setup extensions that should be used to resolve modules (e.g. --resolve-extensions .js,.jsx)
Using --module-bind and --resolve-extensions options,

webpack --module-bind 'js=babel-loader' --module-bind 'jsx=babel-loader' --resolve-extensions .js,.jsx 
Enter fullscreen mode Exit fullscreen mode

mode

Ok, Errors have been resolved 😊
But warning is displayed.

WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment. 
Enter fullscreen mode Exit fullscreen mode

quote from Release Note v4.0.0-beta.0

  • You have to choose (mode or --mode) between two modes now: production or development
    • production enables all kind of optimizations to generate optimized bundles
    • development enables comments and hint for development and enables the eval devtool
    • WIP: addition hints in development mode
    • production doesn't support watching, development is optimized for fast incremental rebuilds
    • production also enables module concatenating (Scope Hoisting)
    • You can configure this in detail with the flags in optimization.* (build your custom mode)
    • process.env.NODE_ENV are set to production or development (only in built code, not in config)
    • There is a hidden none mode which disables everything

--mode option has to be added.

webpack --module-bind 'js=babel-loader' --module-bind 'jsx=babel-loader' --resolve-extensions .js,.jsx --mode production
Enter fullscreen mode Exit fullscreen mode

entry

You can specify the entry point.
--entry src means that the entry point is src/index.js.
--entry src/foo.js means that the entry point is src/foo.js

output

Also, you can specify the output point.
--output public means that the output directory is public.
--output public/index.bundle.js means that the output directory is public and output file name is index.bundle.js.
-o is the shorthand of --output.

Filnal

webpack --module-bind 'js=babel-loader' --module-bind 'jsx=babel-loader' --resolve-extensions .js,.jsx --mode production --entry ./src --output public/index.bundle.js
Enter fullscreen mode Exit fullscreen mode

Other options

You can know the other options with --help option.

webpack --help
Enter fullscreen mode Exit fullscreen mode

Further reading

Thank you.

Discussion (3)

Collapse
evgenyx82 profile image
Evgenyx82

webpack-dev-middleware + webpack-dev-server +

server.js:
...
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
}));
...

webpack.config.js:
...
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)}),
or as u did mention
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production')}),
...

Gives me:
WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.

package.json:
...
"webpack": "4.0.1",
"webpack-cli": "2.0.9"
"webpack-dev-middleware": "3.0.0",
"webpack-dev-server": "3.1.0",
...
it seems most latest versions...

How to set 'mode' while using webpack-dev-middleware + webpack-dev-server, any suggestions? ;)

p.s. webpack via command line works fine ;)

Collapse
shisama profile image
Masashi Hirano Author • Edited

Sorry to reply late.
If your webpack.config.js doesn't have 'mode' property, you have to add 'mode' property into your webpack.config.js.

The below is an example.

module.exports = {
  mode: 'production', // <= It is necessary to resolve the warning
  entry: {
    'index': [
      path.resolve(__dirname, 'src/index.js')
    ]
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'public'),
    publicPath: '/',
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    })
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader',
      },
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
};

Thank you for reading this post.

Collapse
evgenyx82 profile image
Evgenyx82

Hello, Masashi Hirano.

It's seems im miss something in the past, here is examples ) github.com/webpack/webpack/tree/ma...

Anyway, thx ) for response.