kawnah
kawnah

Reputation: 3414

How to import components using webpack?

I'm using a gulpfile with gulp-webpack - I want to split my javascript code into different modules, and have them bundled into a single minified file.

Below are the snippets of what I have for code:

function.js:

var $ = require('jquery');

function init() {
  console.log("piped");
  // main expansion element
  $(".button").click(function() {
    // code goes here, etc
  });
}

module.exports = init;

script.js

import script from './app/js/function.js';

module.exports = script;

webpack-config.js

var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');

module.exports = {
  context: __dirname,
  devtool: debug ? "inline-sourcemap" : null,
  entry: "./app/js/script.js",
  output: {
    path: __dirname + "public/javascripts",
    filename: "scripts.min.js"
  },
  plugins: debug ? [] : [
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
  ],
};

Gulptask:

gulp.task('scripts', function() {
    gulp.src('app/js/script.js')
    .pipe(webpack(require('./webpack.config.js')))
    .pipe(gulp.dest('public/javascripts'))
    .pipe(livereload());
});

This where I'm lost - my task is successfully outputting a scripts.min.js file to the correct directory but I'm getting this error:

Uncaught SyntaxError: Unexpected token import

Am I not importing the import correctly? I'm refering to this documentation https://webpack.js.org/guides/code-splitting/ which is suggesting to simply use the import statement and pointing it to the file that you're referencing.

EDIT: Dusting off my webpack knowledge, so:

I changed:

import function from './app/js/function.js';

module.exports = script;

To:

var function = require('function.js');

module.exports = function;

But my console is now saying:

ERROR in ./app/js/script.js
Module not found: Error: Cannot resolve module 'script.js' in /projects/new-platform-prototype/app/js
 @ ./app/js/script.js 1:10-27

Even though the script is there?

Upvotes: 0

Views: 2568

Answers (3)

Rico Herwig
Rico Herwig

Reputation: 1712

In order to use import you need the babel transpiler and the respective loader for your webpack config.

This is what you need to do:

1. Setup Babel

npm i -D babel-core babel-loader babel-preset-es2015

babel-core is needed to transpile your code to ECMAScript 5, so your browser can understand it. babel-loader is used for webpack and the babel-preset-es2015 is telling babel, how to transpile your code.

Next create a file called .babelrc in your projects root, containing this code: { "presets": ["es2015"] }

2. Configure webpack

Finally, add this bit of code to your existing webpack config:

module: { rules: [{ test: /\.js$/, use: 'babel-loader' }] }

One more thing

To unlock more ECMAScript features, check out the presets and plugins that babel offers and integrate them into your .babelrc. You can find them here.

This answer assumes that you are using webpack in at least version 2.

EDIT

If you use

import {...} from './dir/file';

to import your code and omit the file extension, you need to tell webpack how to resolve this, by adding

resolve: {
  extensions: ['.js']
}

to your webpack config.

This will tell webpack to look for ./dir/file.js instead of just for ./dir/file.

Upvotes: 0

Jake
Jake

Reputation: 1429

import statements are not officially supported yet so you have to use a plugin to transpile your code to currently supported standart.

Check out babel-loader for install and usage instructions.

By the way there is another bundler called rollup which supports imports out of the box.

Edit:

Just decided to put a simple rollup example here since I am big fan of it and it seems you don't know yet which bundler you're going to stick with. :)

Run npm i -g rollup and rollup -c to compile it.

answer.js

export default 42;

util.js

export function print(...args) {
  console.log(...args);
}

index.js

import answer from './answer';
import { print } from './util';

print('The answer is:', answer);

rollup.config.js

export default {
  input: 'index.js',
  output: {
    file: 'bundle.js',
    format: 'iife'
  }
};

Upvotes: 1

JSAdam
JSAdam

Reputation: 46

If I am reading what you have here correctly, the script.js appears to be attempting to import itself. You want to import, I assume the function.js, import {init} from "./function". Sorry I do not know your paths. You also are not executing any code so with script.js you need to run it init().

module.js

export function doesStuff() {}

script.js

import {doesStuff} from "module"

doesStuff();

webpack.config.js

module.exports = {
  context: __dirname,
  devtool: debug ? "inline-sourcemap" : null,
  entry: "./app/js/script.js",
  module: {
    loaders: [{
      test: /.js?$/,
      loader: "babel-loader"
    }]
  },
 output: {
   path: __dirname + "public/javascripts",
   filename: "scripts.min.js"
 },
 ...
};

Upvotes: 1

Related Questions