Search code examples
angularjsnpmwebpackbowerbundling-and-minification

How to migrate from imports using <script> to module bundler?


I have a project which uses Angular. It does not use a task manager nor dependency manager and all libs are stored in repo and included using plain old <script> tag like <script src="libs/angular/angular.min.js"></script>.

I want to modernize the application by introducing a module bundler and automating the build process. The original idea was gulp + bower, but I see that webpack + npm3 are a trend now.

There is no issue with gulp + bower because of things like gulp-inject, but I can’t find anything similar which works with webpack.

Are there any tools which would allow me to use the existing code as it is and write only new modules using webpack?


Solution

  • Here's the solution i've got so far. Since the webpack requires a single entry point per bundle, i still have to import all those legacy js in a single file. So i decided to use ES6 import (or webpack's require) in that entrypoint called index.js

    here's the how webpack config looks like

    var webpack = require('webpack');
    var path = require('path');
    
    var basePath = __dirname + "/target/app";
    module.exports = {
        context: basePath,
        entry: {
            app: './index.js',
            vendor: './vendor.js'
        },
        output: {
            path: basePath + "/build",
            filename: '[name].js'
        },
        module: {
            loaders: [
                {test: /\.js$/, loader: 'babel?presets=es2015', exclude: /node_modules/},
            ]
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor'
            }),
            new webpack.ProvidePlugin({
                "$": "jquery",
                "jQuery": "jquery",
                "window.jQuery": "jquery",
                "_": "lodash"
            }),
        ],
    };
    

    and so in index.js i did following

    import './app/component1.js'
    import './app/component2.js'
    //all the rest imports from index.html
    

    as for the third part libraries like jquery, angular, etc... i decided to describe that imports in separate bundle and so there's another bundle called vendor.js

    import './libs/lodash.js'
    import './libs/jquery.js'
    //and all the rest libraries
    //note that here we can use now libs from npm node_modules like
    import 'angular' //will take angular from node_modules/angular
    

    Important thing which i faced while doing this, is that legacy modules are not really compatible with webpack because of using global variables like $, _, etc... ProvidePlugin helps here and add require({module}) to the modules where the provided {variable} met as it's described in config 'variable': 'module'

    Note that i used CommonsChunkPlugin to avoid having dependent modules in both bundlers, like angular is required in index.js and vendor.js but with this plugin webpack will handle that and add js code only in vendor.js