Kian
Kian

Reputation: 735

webpack 'import' only at the top level

I'm trying to implement async routing in my react-project using react-router-async-routing.

The problem is that I get this error during webpack compiling:

'import' and 'export' may only appear at the top level

It happens in my router.js which is equal to the one from the link above. Replacing the import with System.import compiles without errors and the browser loads the chunk (visible in the network-traffic-view), but the page remains blank (I guess it is not being executed!).

This is my webpack-config:

var { path, resolve } = require("path");
var webpack = require("webpack");

module.exports = {

  entry: {
    app: "./src/js/user/main.js",
    vendor: ["react", "react-dom"]
  },

  output: {
    path: __dirname + "/resources/user/js",
    publicPath: "/resources/user/js/",
    filename: "[name].bundle.js",
    chunkFilename: "[name].bundle.js"
  },

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "vendor.bundle.js"
    })
  ],

  module: {
    loaders: [{
        test: /.(js|jsx)?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['env', 'react']
        }
      },
      {
        test: /\.(less)$/,
        loaders: ["style-loader", "css-loader", "less-loader"]
      },
      {
        test: /\.(css)$/,
        loaders: ["style-loader", "css-loader"]
      },
      {
        test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
        loader: "file-loader"
      },
      {
        test: /\.(png|jpg|gif)$/,
        loader: "url-loader"
      }
    ]
  },

  resolve: {
    alias: {
      "global": __dirname + "/src/js/user/module/global"
    }
  }
};

How can I solve this problem?

EDIT1:

File with error:

import AsyncSetup from "react-router-async-routing";

import routes from "./routes";

const {Route, Link, Preload} = AsyncSetup(routes, path => {
    import(`./routes/${path}.jsx`);
});

export {Link, Route, Preload};

EDIT2: I solved the problem with the import by installing

babel-plugin-syntax-dynamic-import

and adding it to babel :

test : /.(js|jsx)?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
    presets: [['es2015'], 'react'],
    plugins: ["syntax-dynamic-import"]
}

Now everything is working!

Upvotes: 1

Views: 3316

Answers (1)

Luís Brito
Luís Brito

Reputation: 1772

The new Import API is still a little confusing, because of different Node versions, and specially when using transpiling tools such as Babel and Webpack. I strongly recommend you to use require() instead of import() in your dynamic imports (where the file path is not a constant) and let import for constant dependencies, that's what I do in my projects, and I have no issues.

Something like this:

import AsyncSetup from "react-router-async-routing";

import routes from "./routes";

const {Route, Link, Preload} = AsyncSetup(routes, path => {
  return require(`./routes/${path}.jsx`);
});

export {Link, Route, Preload};

You can also use absolute paths, this might be safer depending on your environment and code.

import path from 'path';
import AsyncSetup from "react-router-async-routing";

import routes from "./routes";

const {Route, Link, Preload} = AsyncSetup(routes, path => {
  return require(path.join(__dirname, `./routes/${path}.jsx`));
});

export {Link, Route, Preload};

If this don't solve your issue, maybe you'll need to do some tweaking in the babel/webpack modules resolver.

Upvotes: 1

Related Questions