vue.js - dynamic imports results in error: Support for the experimental syntax 'dynamicImport' isn't currently enabled

Martin James picture Martin James · Feb 2, 2019 · Viewed 9.5k times · Source

I'm learning Vue.js with Webpack for the first time today and trying to get a router working with lazy/dynamic imports.

I want to use lazy/dynamic imports because I am rebuilding my content management system which has many, many pages that may or may not be used during the user's session, so loading the modules they need dynamically, when they need them, makes more sense with regards to my application.

My very basic router currently looks like this:

import Vue from "vue";
import Router from "vue-router";

Vue.use(Router);

function loadView(view) {
    return () => import(/* webpackChunkName: "view-[request]" */ `@/views/${view}.vue`);
}

export default new Router({
    routes: [
        {
            path: "/",
            name: "dashboard",
            component: loadView("Dashboard")
        },
        {
            path: "/login",
            name: "login",
            component: loadView("Login")
        }
    ]
});

However, I run into the following compilation error:

ERROR in ./src/router/index.js Module build failed (from ./node_modules/babel-loader/lib/index.js): SyntaxError: ...../src/router/index.js: Support for the experimental syntax 'dynamicImport' isn't currently enabled

With the additional note:

Add @babel/plugin-syntax-dynamic-import to the 'plugins' section of your Babel config to enable parsing.

And shows me which line is the problem, which is quite obvious anyway:

return () => import(/*..........
             ^

I recognise this error from when I was playing with Webpack on its own a few months ago, so I knew I had to install the dynamic import plugin to make this work.

This is what I installed:

npm install babel-plugin-syntax-dynamic-import

And I made this plugin available in my babel.rc configuration file and ran npm run dev to recompile everything:

{
    "presets": [
        [
            "@babel/env", {
                "modules": false,
                "targets": {
                    "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
                }
            }
        ]
    ],
    "plugins": ["@babel/plugin-syntax-dynamic-import"]
}

But I'm still getting the error and I still can't use dynamic importing features! Am I doing something wrong? Has anybody else had trouble with getting dynamic imports to work?


My webpack.config file:

'use strict';

const webpack = require('webpack');
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    mode: 'development',
    entry: [
        './src/app.js'
    ],
    devServer: {
        hot: true,
        watchOptions: {
            poll: true
        }
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: 'vue-loader'
            },
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.scss$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true,
                            outputStyle: 'compressed',
                            data: `
                                @import "./src/assets/scss/_variables.scss";
                                @import "./src/assets/scss/_mixins.scss";
                            `
                        }
                    }
                ]
            }
        ]
    },
    resolve: {
        alias: {
            "@": path.resolve(__dirname, './src'),
            "Components": path.resolve(__dirname, './src/components/')
        }
    },
    optimization: {
        minimizer: [new UglifyJsPlugin()],
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: true
        })
    ]
}

My package.json file:

{
  "name": "manage_v2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --config build/webpack.config.dev.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.18.0",
    "vue": "^2.5.22",
    "vue-router": "^3.0.2",
    "vuex": "^3.1.0"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/preset-env": "^7.3.1",
    "babel-loader": "^8.0.5",
    "babel-plugin-dynamic-import-webpack": "^1.1.0",
    "css-loader": "^2.1.0",
    "html-webpack-plugin": "^3.2.0",
    "node-sass": "^4.11.0",
    "sass-loader": "^7.1.0",
    "uglifyjs-webpack-plugin": "^2.1.1",
    "vue-loader": "^15.6.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.5.22",
    "webpack": "^4.29.0",
    "webpack-cli": "^3.2.1",
    "webpack-dev-server": "^3.1.14"
  }
}

Answer

Martin James picture Martin James · Feb 2, 2019

I fixed the problem myself after many hours of frustration. I still don't know why the method that's used in the Babel, Webpack and Vue documentation doesn't work but I did get this working:

I first removed the plugin declaration from babel.rc file and then added an option to the babel loader in webpack.config file:

{
    test: /\.js$/,
    use: {
        loader: "babel-loader",
        options: {
            plugins: [
                "@babel/plugin-syntax-dynamic-import"
            ]
        }
    }
}

I hope this helps others.