1. 首先在桌面建一个 webpacktest
    2. 在命令行中进入 webpacktest 文件夹 ``` cd Desktop cd webpacktest
    1. 3. 项目初始化,前提是全局已安装 webpack 这个模块

    npm init

    1. 4. 在项目中新建 webpack.cnfig.js 文件
    2. 4. 在命令行中,给项目装 webpack

    cnpm install webpack —save

    1. 6. 在项目中新建文件夹<br />
    2. assets 为静态资源, .es .less 方便后面的 loader
    3. > assets -> scripts -> index.es<br />
    4. assets -> styles -> index.less<br />
    5. assets -> html
    6. 7. 编辑 index.less

    body{ background:black; h1{ color:yellowgreen; } }

    1. 8. 编辑 index.es 文件

    require(‘../styles/index.less’); const data = 123; console.log(data);

    1. 9. 编辑 index.html 文件

    <!DOCTYPE html>

    <

    Hello Webpack

    1. 10. 编辑 webpack.cnfig.js 文件

    //安装一个路径方法的包,这样就不用那么麻烦的写路径了 const path = require(‘path’); // Webpack2 与 1 还是一样的用这个配置 五个模块 module.exports = { //配置资源入口 entry: { //这里的值如果是多个的话写成数组就可以 了 ‘index’: ‘./assets/scripts/index.es’ }, //配置输出到的位置 output: { //后面的值表示:指定编译之后的文件到哪里去 path: path.join(__dirname, ‘./assets/‘), //这个是资源生成之后在每个文件前面加 ./ 这个是本地这样写 如果是上线的话 要换成 公司对应的网址 https://xxx.com/ publicPath: ‘./‘, //这个实际上是将文件名称生成 index.bundle.js 这样的 filename: ‘scripts/[name].bundle.js’ } //配置 loader 用来处理文件 module: { //这个相当于是将 webpack 1 中的 loaders 写到了这个 rules 里 rules: [{ //要处理的文件 后面是正则匹配的 以.es 结尾的文件 test: /.es$/, //这个是指明用哪些 loader 去处理上面选中的文件 use: [{ loader: ‘babel-loader’, //配置 babel-loader options: { //需要先装 babel-loader 包 } }] }] } }

    1. 11. 安装 loader -> babel-loader

    //-dev 是表示这个包只在生产环境使用,上线就用不着了 cnpm install babel-loader —save-dev

    1. 12. 配置解析 .es 文件的 loader

    { //要处理的文件 后面是正则匹配的 以.es 结尾的文件 test: /.es$/, //这个是指明用哪些 loader 去处理上面选中的文件 use: [{ loader: ‘babel-loader’, //配置 babel-loader options: { ‘presets’: [‘es2015’, ‘stage-0’] } }] }

    1. 13. 配置解析 .less 文件的 loader

    { test: /.less$/i, use: ExtractTextPlugin.extract({ //fallback 的作用是所有的loader 都引用失败了 最后用我这个后面的loader fallback: ‘style-loader’, //正常情况下用的 loader use: [{ loader: ‘css-loader’ }, { loader: ‘less-loader’ }] }) }

    1. 装包
    2. > 参考链接:[https://www.npmjs.com/package/extract-text-webpack-plugin](https://www.npmjs.com/package/extract-text-webpack-plugin)

    cnpm install extract-text-webpack-plugin —save-dev

    1. webpack.config.js 文件中引入

    const ExtractTextPlugin = require(“extract-text-webpack-plugin”);

    1. 装包

    cnpm install style-loader —save-dev cnpm install css-loader —save-dev cnpm install less-loader —save-dev

    1. 14. 此时运行程序 $ webpack,报出如下图所示的错误
    2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-de9b0cd908a8a8c3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<br />
    3. 接续装包

    //不加 -dev 因为在真实的生产环境可能会用到 babel-core cnpm install babel-core —save //babel 编译时一定会用到的两个包 cnpm install babel-preset-es2015 —save-dev cnpm install babel-preset-stage-0 —save-dev

    1. 15. 此时运行程序 $ webpack 还是会报错如下图所示的错误
    2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-04345b0036723e8d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<br />
    3. 需要在 module.exports 中再配一个 plugins 模块

    plugins:[ new ExtractTextPlugin(‘styles/[name].css’) ]

    1. 16. 在执行程序 $ webpack ,报如下错误
    2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-cd21743dbf052068.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<br />
    3. 继续装报错中未找到的包

    cnpm install less —save-dev

    1. 17. 再次执行程序 $ webpack ,编译成功了
    2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-173ec8f002c384b2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    3. 18. 此时会发现在 styles 文件夹下生成了一个 index.css 文件,scripts 文件夹下生成了一个 index.bundle.js 文件<br />
    4. index.css

    body { background: black; } body h1 { color: yellowgreen; }

    1. index.bundle.js

    /**/ (function(modules) { // webpackBootstrap /**/ // The module cache /**/ var installedModules = {}; /**/ /**/ // The require function /**/ function webpack_require(moduleId) { /**/ /**/ // Check if module is in cache /**/ if(installedModules[moduleId]) { /**/ return installedModules[moduleId].exports; /**/ } /**/ // Create a new module (and put it into the cache) /**/ var module = installedModules[moduleId] = { /**/ i: moduleId, /**/ l: false, /**/ exports: {} /**/ }; /**/ /**/ // Execute the module function /**/ modules[moduleId].call(module.exports, module, module.exports, webpack_require); /**/ /**/ // Flag the module as loaded /**/ module.l = true; /**/ /**/ // Return the exports of the module /**/ return module.exports; /**/ } /**/ /**/ /**/ // expose the modules object (webpack_modules) /**/ webpack_require.m = modules; /**/ /**/ // expose the module cache /**/ webpack_require.c = installedModules; /**/ /**/ // define getter function for harmony exports /**/ webpack_require.d = function(exports, name, getter) { /**/ if(!webpack_require.o(exports, name)) { /**/ Object.defineProperty(exports, name, { /**/ configurable: false, /**/ enumerable: true, /**/ get: getter /**/ }); /**/ } /**/ }; /**/ /**/ // getDefaultExport function for compatibility with non-harmony modules /**/ webpack_require.n = function(module) { /**/ var getter = module && module.esModule ? /**/ function getDefault() { return module[‘default’]; } : /**/ function getModuleExports() { return module; }; /**/ webpackrequire.d(getter, ‘a’, getter); /**/ return getter; /**/ }; /**/ /**/ // Object.prototype.hasOwnProperty.call /**/ webpackrequire.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /**/ /**/ // webpackpublicpath /**/ webpackrequire.p = “./“; /**/ /**/ // Load entry module and return exports /**/ return webpackrequire(__webpack_require.s = 0); /**/ }) /**/ /**/ ([ / 0 / /*/ (function(module, exports, __webpack_require) {

    “use strict”;

    webpack_require(1); var data = 123; console.log(data);

    // }), / 1 / // (function(module, exports) {

    // removed by extract-text-webpack-plugin

    // }) /*/ ]);

    1. 19. 此时会发现写了一点东西编译出来的就这么的复杂,所以需要化简<br />
    2. webpack.config.js 文件中引入 webpack

    //头部引用 const webpack = require(‘webpack’);

    //plugins -> 配置里新增 //生成一个公用的 如果有两个以上的文件同样的引用一样的js 代码 它就会生成一个 common.js 文件 new webpack.optimize.CommonsChunkPlugin({ name:’common’, filename:’scripts/[name].js’, //引用了两次以上 minChunks:2 })

    1. 20. 执行程序 $ webpack<br />
    2. 查看 scripts 文件夹多了一个 common.js 文件<br />
    3. common.js

    /**/ (function(modules) { // webpackBootstrap /**/ // install a JSONP callback for chunk loading /**/ var parentJsonpFunction = window[“webpackJsonp”]; /**/ window[“webpackJsonp”] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { /**/ // add “moreModules” to the modules object, /**/ // then flag all “chunkIds” as loaded and fire callback /**/ var moduleId, chunkId, i = 0, resolves = [], result; /**/ for(;i < chunkIds.length; i++) { /**/ chunkId = chunkIds[i]; /**/ if(installedChunks[chunkId]) { /**/ resolves.push(installedChunks[chunkId][0]); /**/ } /**/ installedChunks[chunkId] = 0; /**/ } /**/ for(moduleId in moreModules) { /**/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { /**/ modules[moduleId] = moreModules[moduleId]; /**/ } /**/ } /**/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); /**/ while(resolves.length) { /**/ resolves.shift()(); /**/ } /**/ if(executeModules) { /**/ for(i=0; i < executeModules.length; i++) { /**/ result = webpack_require(webpack_require.s = executeModules[i]); /**/ } /**/ } /**/ return result; /**/ }; /**/ /**/ // The module cache /**/ var installedModules = {}; /**/ /**/ // objects to store loaded and loading chunks /**/ var installedChunks = { /**/ 1: 0 /**/ }; /**/ /**/ // The require function /**/ function webpack_require(moduleId) { /**/ /**/ // Check if module is in cache /**/ if(installedModules[moduleId]) { /**/ return installedModules[moduleId].exports; /**/ } /**/ // Create a new module (and put it into the cache) /**/ var module = installedModules[moduleId] = { /**/ i: moduleId, /**/ l: false, /**/ exports: {} /**/ }; /**/ /**/ // Execute the module function /**/ modules[moduleId].call(module.exports, module, module.exports, webpack_require); /**/ /**/ // Flag the module as loaded /**/ module.l = true; /**/ /**/ // Return the exports of the module /**/ return module.exports; /**/ } /**/ /**/ // This file contains only the entry chunk. /**/ // The chunk loading function for additional chunks /**/ webpack_require.e = function requireEnsure(chunkId) { /**/ var installedChunkData = installedChunks[chunkId]; /**/ if(installedChunkData === 0) { /**/ return new Promise(function(resolve) { resolve(); }); /**/ } /**/ /**/ // a Promise means “currently loading”. /**/ if(installedChunkData) { /**/ return installedChunkData[2]; /**/ } /**/ /**/ // setup Promise in chunk cache /**/ var promise = new Promise(function(resolve, reject) { /**/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; /**/ }); /**/ installedChunkData[2] = promise; /**/ /**/ // start chunk loading /**/ var head = document.getElementsByTagName(‘head’)[0]; /**/ var script = document.createElement(‘script’); /**/ script.type = ‘text/javascript’; /**/ script.charset = ‘utf-8’; /**/ script.async = true; /**/ script.timeout = 120000; /**/ /**/ if (webpack_require.nc) { /**/ script.setAttribute(“nonce”, webpack_require.nc); /**/ } /**/ script.src = webpack_require.p + “scripts/“ + chunkId + “.bundle.js”; /**/ var timeout = setTimeout(onScriptComplete, 120000); /**/ script.onerror = script.onload = onScriptComplete; /**/ function onScriptComplete() { /**/ // avoid mem leaks in IE. /**/ script.onerror = script.onload = null; /**/ clearTimeout(timeout); /**/ var chunk = installedChunks[chunkId]; /**/ if(chunk !== 0) { /**/ if(chunk) { /**/ chunk1); /**/ } /**/ installedChunks[chunkId] = undefined; /**/ } /**/ }; /**/ head.appendChild(script); /**/ /**/ return promise; /**/ }; /**/ /**/ // expose the modules object (webpack_modules) /**/ webpack_require.m = modules; /**/ /**/ // expose the module cache /**/ webpack_require.c = installedModules; /**/ /**/ // define getter function for harmony exports /**/ webpack_require.d = function(exports, name, getter) { /**/ if(!webpack_require.o(exports, name)) { /**/ Object.defineProperty(exports, name, { /**/ configurable: false, /**/ enumerable: true, /**/ get: getter /**/ }); /**/ } /**/ }; /**/ /**/ // getDefaultExport function for compatibility with non-harmony modules /**/ webpack_require.n = function(module) { /**/ var getter = module && module.esModule ? /**/ function getDefault() { return module[‘default’]; } : /**/ function getModuleExports() { return module; }; /**/ webpackrequire.d(getter, ‘a’, getter); /**/ return getter; /**/ }; /**/ /**/ // Object.prototype.hasOwnProperty.call /**/ webpackrequire.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /**/ /**/ // webpackpublicpath /**/ webpack_require.p = “./“; /**/ /**/ // on error function for async loading /**/ __webpack_require.oe = function(err) { console.error(err); throw err; }; /**/ }) /**/ /**/ ([]);

    1. 同时会发现 index.bundle.js 文件发生了改变 简化了很多,其实是把公用的 js 放到了 comment.js 文件中

    webpackJsonp([0],[ / 0 / /*/ (function(module, exports, webpack_require) {

    “use strict”;

    webpack_require(1); var data = 123; console.log(data);

    // }), / 1 / // (function(module, exports) {

    // removed by extract-text-webpack-plugin

    /*/ }) ],[0]);

    1. 21 . 编辑 html 文件,在浏览器中打开,并查看 js 是否编译成功了<br />
    2. index.html

    <!DOCTYPE html>

    <

    Hello Webpack

    1. 效果如下图所示
    2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-7479fb58b741811a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    3. 22. 接下来装一个 可以将资源 自动引入 html 的插件
    4. > 参考链接:[https://www.npmjs.com/package/html-webpack-plugin](https://www.npmjs.com/package/html-webpack-plugin)

    cnpm install html-webpack-plugin —save-dev

    1. 23. 编辑 wepack.config.js 文件

    const HtmlWebpackPlugin = require(‘html-webpack-plugin’);

    
    24. 在项目一级目录下新建一个 index.html 文件<br />
    index.html
    

    <!DOCTYPE html>

    Hello Webpack

    将 assets -> index.html 文件中的代码全部删掉<br />
    25.  编辑 wepack.config.js 文件
    

    //plugins -> 配置里新增 new HtmlWebpackPlugin({ //生成的新文件的名称 路径的话 以上面配置的 output path: path.join(__dirname, ‘./assets/‘) 为基准 filename:’index.html’, //生成的新 html 文件 用到的 html 文件 template:’./index.html’, inject:true })

    
    26. 执行程序 $ webpack<br />
    此时 assets -> index.html 文件中的代码是自动将 html 和 引入 .css .js 的代码合并到一起的<br />
    assets -> index.html
    

    <!DOCTYPE html>

    Hello Webpack

    
    27. 注意一个问题是,上线时生成资源的路径要改为线上的地址
    
    > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-aaeb04a93309bf2f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<br />
    如:[https://xxxx.com/](https://xxxx.com/)      执行程序  $ webapck<br />
    html 生成的结果会如下图所示的这样<br />
    ![image.png](http://upload-images.jianshu.io/upload_images/9064013-547b924166681053.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    28. 接下来是 webpack2 优良性的一些东西<br />
    首先是会将你 js 文件中没用到的 js 变量自动给你去掉,在 scripts 文件夹中新建一个 data.es 文件<br />
    编辑  data.es 文件
    

    //es6 Map 参考链接:http://es6.ruanyifeng.com/#docs/set-map#Map const m = new Map(); m.set(‘data’,’Index init’); //导出一个函数 export const test = function() { console.log(‘test treeShaking’); } //导出一个属性值 export const data = m.get(‘data’);

    编辑 index.es 文件
    

    require(‘../styles/index.less’); import {data} from ‘./data.es’; // const data = 123; console.log(data);

    执行程序 $ webpack<br />
    index.bundle.js 文件会显示如下
    

    webpackJsonp([0],[ / 0 / /*/ (function(module, exports, webpack_require) {

    “use strict”;

    var data = _webpack_require(1);

    webpack_require(2);

    // const data = 123; console.log(_data.data);

    // }), / 1 / // (function(module, exports, webpack_require) {

    “use strict”;

    Object.defineProperty(exports, “__esModule”, { value: true }); //es6 Map 参考链接:http://es6.ruanyifeng.com/#docs/set-map#Map var m = new Map(); m.set(‘data’, ‘Index init’); //导出一个函数 var test = exports.test = function test() { console.log(‘test treeShaking’); }; //导出一个属性值 var data = exports.data = m.get(‘data’);

    // }), / 2 / // (function(module, exports) {

    // removed by extract-text-webpack-plugin

    /*/ }) ],[0]);

    发现这里并没有把没用到的 test 函数去掉,需要配置一个插件才行是编辑 webpack.config.js 文件
    

    //plugins -> 配置里新增 //这个是 webpack 自带的模块 不需要装 new webpack.optimize.UglifyJsPlugin({ compress:{ warnings:true }, output:{ comments:false }, sourceMap:false })

    执行程序 $ webpack
    
    > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-8957e71ea29c6951.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<br />
    上面有两处警告,此时去查看压缩过的 index.bundle.js 文件,会发现 test 函数 它还在,是因为上面的 babel 编译机制把它给留下了需要改变 babel  ->  es2015 的参数<br />
    编辑 webpack.config.js 文件
    

    //module -> rules 配置里新增 //配置 babel-loader options: { ‘presets’: [ [‘es2015’, { ‘modules’: false }], ‘stage-0’ ] }

    命令行中显示结果如下
    
    > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-73644cfc7b2ca5bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<br />
    再去查看 index.bundle.js 文件会发现 test 函数已经被去掉了
    
    
    29. 这时你会想自己写的 js 只是想做一个简单点的事,但是编译的时候会把每个函数都编译成闭包 作用域,这样做有些有违常理,随着 webpack3 的更新,出了一个 scope hoisting 的东西
    
    > 参考链接:[https://zhuanlan.zhihu.com/p/27828233](https://zhuanlan.zhihu.com/p/27828233)
    

    //plugins -> 配置里新增 //这个插件是 webpack3 才有的它比之前的 new webpack.optimize.UglifyJsPlugin() 方法更好地将 js 代码简化了 new webpack.optimize.ModuleConcatenationPlugin()

    执行程序 $ webpack  此时去查看 index.bundle.js 文件发现比刚才又精简了一些<br />
    30.  举两个简单的示例<br />
    编辑 index.es 文件<br />
    示例1:
    

    if(false == false){ console.log(1); }

    执行程序  $ webpack ,在查看 index.bundle.js (.es 编译后的)文件,会发现上面的 if 判断直接就给你去掉了,直接将里面的console 拿了出来<br />
    示例2:
    

    if(false != false){ console.log(1); }

    执行程序  $ webpack ,在查看 index.bundle.js (.es 编译后的)文件,会发现上面的 if 判断本身是错误的东西 它会自动将整个 if 判断包含里面的代码全都给你去掉<br />
    31.  还要完成一个东西 代码分割 code splitting<br />
    在 scripts 文件夹中新建一个 async.es 文件<br />
    编辑 async.es 文件
    

    const res = function() { console.log(‘async res’); } export default res;

    编辑 index.es 文件
    

    //加载 async.es 文件导出的函数 res 并执行该函数 import(‘./async.es’).then(function(res) { res.default(); });

    执行程序 $ webpack ,此时会发现在 scripts 文件夹中自动生成了一个 0.bundle.js 文件,这个是webpack 自动将你异步处理的 js 方法直接新建了一个 js 文件放到了里面,这个东西不会自动引入到 html 中,如果引入了就变成同步了,这个东西是在到服务器上的,会通过 load 异步的资源把它请求过去 这个就是所谓的代码分割<br />
    32.  还有其他的需要上线的时候掌握的东西,上面的这些掌握基本就可以了,还有如下这样的例子
    

    //与 plugins 模块平级的 //这个里面是将引用的一些公共 模块放到这里,这样就可以全局使用了,避免重复调用 引用的话还是用 cdn 引用静态资源库里的东西 externals:{ jquery:’window.$’ },

    ```