Search code examples
webpackgulpbabeljswebpack-2

Webpack : Using with bower


Main question: How can I translate my current situation to an webpack.config.json , using babel preset es2015, babel-polyfill and babelify ?
I have used Bower and my bower.json file is like this :

"dependencies": {
    "adminlte": "almasaeed2010/AdminLTE#2.4.0-alpha",
    "jquery": "^3.2.1",
    "font-awesome": "^4.7.0",
    "Ionicons": "ionicons#^2.0.1",
    "lobibox": "^1.2.4",
    "moment-timezone": "^0.5.12",
    "eonasdan-bootstrap-datetimepicker": "https://github.com/Eonasdan/bootstrap-datetimepicker.git#^4.17.47",
    "bootstrap-table": "^1.11.1",
    "parsleyjs": "^2.7.0",
    "bootstrap-daterangepicker": "https://github.com/dangrossman/bootstrap-daterangepicker.git#2.1.25",
    "socket.io-client": "^1.7.2",
    "jquery-confirm2": "^3.2.0",
    "push.js": "^0.0.13",
    "lodash": "^4.17.4",
    "tableExport.jquery.plugin": "^1.8.2"
  }

The js files I load are the following :

<!-- jQuery 3.X -->
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap 3.3.6 -->
<script src="/bower_components/adminlte/bootstrap/js/bootstrap.min.js"></script>
<!-- FastClick -->
<script src="/bower_components/adminlte/plugins/fastclick/fastclick.js"></script>
<!-- Lobibox Notifications -->
<script src="/bower_components/lobibox/dist/js/notifications.min.js"></script>
<!-- AdminLTE App -->
<script src="/bower_components/adminlte/dist/js/app.min.js"></script>
<!-- Moment.js -->
<script src="/bower_components/moment/moment.js"></script>
<!-- Moment.js Local => FR -->
<script src="/bower_components/moment/locale/fr.js"></script>
<!-- Moment.js Timezone -->
<script src="/bower_components/moment-timezone/builds/moment-timezone-with-data.min.js"></script>
<!-- DatePicker -->
<script src="/bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js"></script>
<!-- Date Range Picker -->
<script src="/bower_components/bootstrap-daterangepicker/daterangepicker.js"></script>
<!-- Select2 -->
<script src="/bower_components/adminlte/plugins/select2/select2.full.min.js"></script>
<!-- Parsley Validation -->
<script src="/bower_components/parsleyjs/dist/parsley.min.js"></script>
<!-- Parsley Validation language -->
<script src="/bower_components/parsleyjs/dist/i18n/fr.js"></script>
<!-- Bootstrap Table -->
<script  src="/bower_components/bootstrap-table/dist/bootstrap-table.min.js"></script>
<!-- Bootstrap Table Local language-->
<script  src="/bower_components/bootstrap-table/dist/locale/bootstrap-table-fr-BE.min.js"></script>
<!-- Bootstrap Table : Export -->
<script  src="/bower_components/bootstrap-table/dist/extensions/export/bootstrap-table-export.min.js"></script>
<script  src="/bower_components/tableExport.jquery.plugin/tableExport.min.js"></script>
<!-- jquery-confirm -->
<script src="/bower_components/jquery-confirm2/dist/jquery-confirm.min.js"></script>
<!-- Socket.io Client -->
<script src="/bower_components/socket.io-client/dist/socket.io.js"></script>
<!-- Lodash -->
<script src="/bower_components/lodash/dist/lodash.min.js"></script>
<!-- Push Js -->
<script src="/bower_components/push.js/push.min.js"></script>
<!-- Google Chart -->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

<!-- All my JS to enable interaction -->
<script src="/dist/js/unitedJs.js"></script>

Warning : The unitedJs.js is all the custom Js merged together . I can easily make them webpack 2 compatible (For "entry", I have a main.js).

my gruntfile (for creating this unitedJs.js) :

const gulp = require('gulp');
const babel = require('gulp-babel');
const concat = require('gulp-concat');
const sourcemaps = require('gulp-sourcemaps');
const Path = require("path");
// default babel-polyfill require : .../lib/index.js
// Goal : ../dist/polyfill.min.js
// If you really want to know WHY I must do this : check https://github.com/babel/gulp-babel/issues/27
let polyfillPath = Path.relative(__dirname, Path.join(require.resolve("babel-polyfill"), "../..", "dist/polyfill.min.js"));

gulp.task('js', function () {

    return gulp.src(['public/js/*.js', polyfillPath])
        .pipe(sourcemaps.init())
        .pipe(babel({
            presets: ['es2015']
        }))
        .pipe(concat('unitedJs.js'))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('public/dist/js'));
});


// Watch Files For Changes
// Thanks https://travismaynard.com/writing/getting-started-with-gulp

gulp.task('watch', function () {
    gulp.watch('public/js/*.js', ['js']);
});

gulp.task('default', ['js', 'watch']);

PS: I already read some posts here but I didn't find an answer :
Managing jQuery plugin dependency in webpack
https://webpack.github.io/docs/usage-with-bower.html (I know it is webpack 1 doc but I didn't find it in V2 doc)
Webpack with bower support


Solution

  • I'd like to start by saying this is just to get you started, to get you ready for production I'd suggest you really read up on core concepts of webpack and babel. Also, all of the following assume's your on a mac.

    1. install brew, copy and paste in terminal the following:

    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    
    1. install node: brew install node

    2. install nvm: brew install nvm

    3. make new dir(to start your new project and not compromise your current work) an cd into it :

      paste the following into terminal, sequentially.

      • npm init -y
      • npm install -D webpack webpack-dev-server
      • npm install -D babel-cli babel-preset-env babel-core babel-loader babel-polyfill babel-preset-es2015
    4. Create webpack.config.js in the root of your project.(see example of simple webpack config below)

    5. make index.html file
    6. you'll need to require all dependencies in your app.js file via your prefered method.
    7. set in package.json the start command to the following:

      "start": "webpack-dev-server --env=dev --progress --watch --content-base src/app",

    Sources to read up on for better step by step:

    ignore the angular stuff if it's not your flavor. treehouse & angular-tips

    simple webpack config:

    var webpack = require('webpack');
    module.exports = {
      context: __dirname + '/app',
      entry: {
        app: './app.js',
        // add all of you bower dependecies here, you must **npm install --save** each package
        vendor: ['angular']
      },
      output: {
        path: __dirname + '/js',
        filename: 'app.bundle.js'
      },
      module: {
        rules: [{
          test: /\.js$/,
          use: 'babel-loader',
          exclude: /node_modules/
        }]
      },
      plugins: []
    };
    
    
    // make a .babelrc file in root dir and include the following. optionally you can look at babel docs to use these options in the webpack config file.
    
    {
      "sourceMaps": true,
      "env": {
        "testing": {
          "presets": [
            "es2015"
          ]
        }
      },
      "presets": [
        ["es2015"]
      ]
    }
    

    Edit: comprehensive config

    const webpack = require('webpack');
    const path = require('path');
    // you'll need to npm install the following: [raw-loader, html-minifier-loader, json-loader, css-loader,style-loader, url-loader, file-loader ]
    // in your index.html you should have two script tags, one for app.js(or bundle.js) and vendor.js
    // no need for babelify with webpack. just, npm install --save-dev babel-cli babel-preset-es2016
    // in .babelrc file change the preset of 2015 to ["es2016"]
    module.exports = {
      entry: {
        app: './app.js',
        // if any on these are just for css remove them from here and require(with absolute path) them from app.js
        vendor: [
          'babel-polyfill',
          'adminlte',
          'jquery',
          'font-awesome',
          'Ionicons',
          'lobibox',
          'moment-timezone',
          'eonasdan-bootstrap-datetimepicker',
          'bootstrap-table',
          'parsleyjs',
          'bootstrap-daterangepicker',
          'socket.io-client',
          'jquery-confirm2',
          'push.js',
          'lodash',
          'tableExport.jquery.plugin'
        ]
      },
      devtool: 'eval',
      output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'),
        pathinfo: true
      },
      module: {
        rules: [{
          test: /\.js$/,
          use: 'babel-loader',
          exclude: /node_modules/
        }, {
          test: /\.html$/,
          use: ['raw-loader', 'html-minifier-loader'],
          exclude: /node_modules/
        }, {
          test: /\.json$/,
          use: 'json-loader',
          exclude: /node_modules/
        }, {
          test: /\.css$/,
          use: 'css-loader',
          exclude: /node_modules/
        }, {
          test: /\.(jpg|png|gif)$/,
          use: 'file-loader',
          exclude: /node_modules/
        }, {
          test: /\.(woff|woff2|eot|ttf|svg)$/,
          use: {
            loader: 'url-loader',
            options: {
              limit: 100000
            }
          },
          exclude: /node_modules/
        }],
      },
      plugins: [],
    };