Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use webpack with babel-loader and flow

I'm struggling with what I feel shouldn't be too hard of a setup. I want these three technologies to work together:

  • webpack to bundle code
  • babel so that I'm able to write modern JavaScript
  • flow because type checking is helpful just like tests and linter

I've already gone trough several setups of this but none of the articles I've found on the web appears to be helpful.


I've defined 3 scripts in my package.json, run, flow and build. Typechecking with yarn run flow works perfectly, and so does executing the script trough babel-node using yarn run start.

But when I execute yarn run build the following error appears trough webpack:

$ ./node_modules/webpack/bin/webpack.js
Hash: 207d42dac5784520fc99
Version: webpack 3.10.0
Time: 49ms
    Asset     Size  Chunks             Chunk Names
bundle.js  2.65 kB       0  [emitted]  main
   [0] ./src/main.js 181 bytes {0} [built] [failed] [1 error]

ERROR in ./src/main.js
Module parse failed: Unexpected token (3:5)
You may need an appropriate loader to handle this file type.
| // @flow
|
| type Foo = {
|   foo: string,
| };
error Command failed with exit code 2.

It appears to me that the type annotations don't get removed correctly at the right point. Sadly this also happend if I specify the babel options in webpack directly as opposed to the .babelrc.

This currently defeats me in bundling up a bunch of .js files whilst using flow and while I found several plugins that supposedly strip flow annotations simply using the flow preset is what flowtype.org appears to recommend.


For reproducibillity, my project files look like this:

package.json:

{
  …
  "dependencies": {},
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-eslint": "^8.0.3",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-flow": "^6.23.0",
    "flow-bin": "^0.60.1",
    "webpack": "^3.9.1"
  },
  "scripts": {
    "build": "./node_modules/webpack/bin/webpack.js",
    "start": "./node_modules/babel-cli/bin/babel-node.js src/main.js",
    "flow": "./node_modules/flow-bin/cli.js"
  }
}

.flowconfig:

[include]
./src

[ignore]

[libs]

[lints]

[options]

.babelrc:

 {
   "presets": ["env", "flow"]
 }

webpack.config.js:

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

module.exports = {
  entry: './src/main.js',
  output: {
    path: __dirname,
    filename: 'bundle.js',
  },
  resolve: {
    modules: [
      path.resolve('./src/'),
      'node_modules',
    ],
    extensions: ['.js'],
  },
  module: {
    rules: [
      {
        test: '/.js$/',
        loader: 'babel-loader',
      },
    ],
  },
};

src/main.js:

// @flow

type Foo = {
  foo: string,
};

const defaultFoo: Foo = {
  foo: 'bar',
};

console.log(defaultFoo);
like image 408
Jakob Runge Avatar asked Dec 13 '17 22:12

Jakob Runge


People also ask

Can I use Babel with Webpack?

There is a specific folder structure to be followed when using Webpack and Babel in your project. We need two separate folders, dist for the output files and src for the input files. You have to keep the index. html file inside the dist folder.

Does Babel run before Webpack?

For . js and . jsx files, we tell Webpack to use babel-loader which makes Webpack run these files through Babel before bundling them.

What is babel-loader in Webpack?

sass-loader compiles SASS files to CSS. babel-loader transpiles JS code given the presets. Plugins are the core of Webpack. They can do things that loaders can't. For example, there is a plugin called UglifyJS that minifies and uglifies the output of webpack.

What does Webpack command in Babel do?

Now let us try to compile to a single file using webpack and babel. We will use webpack to bundle multiple js files into a single file. Babel will be used to compile the es6 code to es5.


1 Answers

Download the relevant presets and add them to the webpack.config.js as follows:

module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['es2015', 'stage-0', 'react']
        }
      }
    }
  ]
}
like image 142
jclyons52 Avatar answered Oct 16 '22 02:10

jclyons52