一步一步学WebPack 2

作者: wavesnow | 来源:发表于2017-06-21 16:15 被阅读96次

    一步一步学WebPack2

    最近将webpack的使用总结一下,便于下一步的使用。本文通过若干的demo,让你一步一步学会使用webpack。webpack中一切都是模块,所有的一切(JS,CSS,图片,HTML)都可以被视作模块,通过require加载。模块加载器会把所有的模块最终打包生成一个巨大的“bundle.js”文件,并且会一直不停进行加载!所以Webpack通过大量的特性去分割你的代码,生成多个“bundle”片段,并且异步地加载项目的不同部分。

    npm install http-server -g
    

    Demo1 - Start

    • 建立node项目:npm init ,名字为demo1,得到package.json文件
    {
      "name": "demo1",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "repository": {
        "type": "git",
        "url": "git+https://github.com/fujusong/webpack-starter.git"
      },
      "keywords": [
        "webpack",
        "starter"
      ],
      "author": "sofu",
      "license": "MIT",
      "bugs": {
        "url": "https://github.com/fujusong/webpack-starter/issues"
      },
      "homepage": "https://github.com/fujusong/webpack-starter#readme",
      "devDependencies": {
        "webpack": "^2.6.1"
      }
    }
    
    • 创建index.html ,并新建一个id为app的div。
    #touch index.html
    #vi index.html
    
    <!DOCTYPE html> 
    <head> 
    <title></title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></script> 
    </head> 
    <body> 
    <div id="app"></div> 
    </body> 
    </html>
    
    
    • 创建index.js
    #touch index.js
    
    var app=document.getElementById('app'); 
    app.innerHTML="Hello My WebPack App";
    
    • 安装webpack开发依赖
    npm install webpack –-save-dev
    
    • 利用webpack将index.js文件打包为bundle.js文件
    ./node_modules/webpack/bin/webpack.js index.js bundle.js 
    
    
    • 修改index.html文件,加入bundle.js。
    <!DOCTYPE html> 
    <head> 
    <title></title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></script> 
    </head> 
    <body> 
    <div id="app"></div> 
    <script src="bundle.js"></script> 
    </body> 
    </html>
    
    
    • 运行http-server,打开浏览器查看页面
    http-server -p 8000
    

    然后在浏览器打开http://localhost:8000

    Demo2 - Data Update

    • 创建src和dist两个文件夹,把index.js移动到src文件夹里,bundle.js是webpack打包生成出来的,使用先删除再生成的办法确保文件正常更新,以后会把dist作为生成文件存放的目标文件夹。
    • 安装rimraf 用于打包前删除旧的生成文件。
    npm install rimraf –-save-dev
    
    • 修改package.json的script启动方式
    {
      "name": "demo1",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build":"rimraf dist && webpack src/index.js dist/bundle.js"
      },
      "repository": {
        "type": "git",
        "url": "git+https://github.com/fujusong/webpack-starter.git"
      },
      "keywords": [
        "webpack",
        "starter"
      ],
      "author": "sofu",
      "license": "MIT",
      "bugs": {
        "url": "https://github.com/fujusong/webpack-starter/issues"
      },
      "homepage": "https://github.com/fujusong/webpack-starter#readme",
      "devDependencies": {
        "rimraf": "^2.6.1",
        "webpack": "^2.6.1"
      }
    }
    
    
    • 运行 npm run build 打包一下,在dist目录下得到了bundle.js
    • 把index.html里面引用bundle.js的路径改成./dist/bundle.js,再运行http-server。

    引入Module,文件监控。

    • 接下来在src目录下新建messages.js文件
    module.exports={ data:'Hello,World!', event:'APP Event'};
    
    • 在index.js文件引入messages.js,并实例到页面
    var messages=require('./message');
    
    var app=document.getElementById('app'); 
    app.innerHTML = messages.data+"From "+ messages.event;
    
    • 把package.json修改一下,build的结尾加上监视命令–watch
    "build":"rimraf dist && webpack src/index.js dist/bundle.js --watch"
    
    • 运行npm run build重新打包,可以看到打包过程并没有结束跳出,仍然是待命状态。
    • 另起一个cli,启动http-server -p 8000,在浏览器输入localhost:8000
    • 修改messages.json消息内容,然后刷新浏览器,可以看到内容随即更新了。

    Demo3 - Webpack-dev-server 1

    • 安装webpack-dev-server
    npm install webpack-dev-server –-save-dev
    
    • 创建webpack.config.js文件,并添加基本配置
    var path = require('path'); // 导入路径包 
    
    module.exports={ 
        entry:'./src/index.js',//入口文件 
        output:{ 
            path:path.join(__dirname,'dist'),// 指定打包之后的文件夹 
            publicPath:'/dist/',// 指定资源文件引用的目录 
            filename:'bundle.js'// 指定打包为一个文件 bundle.js 
        }
    }
    
    • 打包所需的路径都已在webpack.config.js配置后,package.json的build则去掉路径,并添加webpack-dev-server启动:"dev":"webpack-dev-server"
    ... 
    "scripts": { 
    "test": "echo \"Error: no test specified\" && exit 1", 
    "build": "rimraf dist && webpack --watch", 
    "dev": "webpack-dev-server" 
    }, 
    ...
    
    
    • 运行npm run dev启动webpack-dev-server进行打包,在浏览器输入localhost:8080直接打开。
    • 修改messages.json的内容,保存,可以看到浏览器实时更新了数据

    Demo4 - Webpack-dev-server 2

    对于webpack-dev-server,每次修改代码后,webpack可以自动重新打包,webpack-dev-server有两个用于自动刷新模式:iframe和inline,浏览器可以响应代码变化并自动刷新(hot)。

    iframe

    页面被嵌套在一个iframe下,代码发生改动后,iframe会重新加载
    使用此模式无需额外配置,只需访问http://localhost:8080/webpack-dev-server/index.html即可,显然webpack-dev-server默认的模式就是iframe。

    inline

    为整个页面提供了“Live reloading”功能。webpack官方提供的一个小型Express服务器。

    hot

    提供了“模块热重载”功能,它会尝试仅仅更新组件被改变的部分(而不是整个页面)。会尝试先去通过 HMR 更新然后可能尝试刷新整个页面。只需要加上一个 webpack/hot/dev-server entry point,并且在 dev-server 调用时加上参数 –hot。如果我们把inline和hot这两个选项都写上,那么当文件被改动时,webpack-dev-server会先尝试HMR,如果这不管用,它就会重新加载整个页面。

    hot(HMR)和inline使用有两种方式:CLI和Node.js API

    CLI方式比较简单,只需修改package.json中scripts配置,添加 –inline –hot

    "dev": "webpack-dev-server –inline –hot"
    

    node.js API方式

    • 在主目录下,新建dev-server.js文件
    var WebpackDevServer=require('webpack-dev-server'); 
    var webpack=require('webpack'); 
    var config=require('./webpack.config'); 
    var path=require('path'); 
    var compiler=webpack(config); 
    var server=new WebpackDevServer(
        compiler,
        {//创建服务器实例 
            hot:true,//HMR配置 
            filename:config.output.filename, 
            publicPath:config.output.publicPath,//必填 
        stats:{ 
            colors:true 
            } 
        }
    ); 
    server.listen(8080,'localhost',function(){});
    
    • 修改webpack.config.js配置
    var path=require('path');// 导入路径包 
    var webpack=require('webpack'); 
    module.exports={ 
        entry:[//入口文件 
            './src/index.js', 
            'webpack/hot/dev-server',//调用热重载 hot 
            'webpack-dev-server/client?http://localhost:8080'
            //添加webpack-dev-server客户端 
        ], 
        plugins:[ 
            new webpack.HotModuleReplacementPlugin()//全局开启热代码替换 
        ], 
        output:{ 
            path:path.join(__dirname,'dist'),// 指定打包之后的文件夹 
            publicPath:'/dist/',// 指定资源文件引用的目录 
            filename:'bundle.js'// 指定打包为一个文件 bundle.js 
        } 
    }
    
    • 在index.js最底下添加hot调用
    if(module.hot){//启用热重载 
        module.hot.accept();
    }
    
    • 修改package.json启动方式
    ... 
    "scripts": { 
    "build": "rimraf dist && webpack --watch", 
    "dev": "node dev-server.js" 
    }, 
    ...
    
    • 运行npm run dev ,在浏览器输入localhost:8080查看,然后尝试修改index.jsmessages.json的数据,保存,浏览器自动刷新了

    Demo5 - Development and Production

    在入口处区分生产环境和开发环境。

    • 修改package.json的script项,通过set NODE_ENV来设置环境变量
    ...
    "scripts": { 
    "build": "rimraf dist && set NODE_ENV=production&& webpack", 
    "dev": "set NODE_ENV=development&& node dev-server.js" 
    },
    ...
    
    • 修改webpack.config.js,在入口处添加NODE_ENV环境判断使用生产环境还是开发环境的入口文件及插件。process.env.NODE_ENV可以获取到启动文件的环境变量,nodejs的app.get('env')也可以取得。
    var path=require('path');
    var webpack=require('webpack'); 
    var DEVELOPMENT=process.env.NODE_ENV==='development'; 
    var PRODUCTION=process.env.NODE_ENV==='production'; 
    var entry=PRODUCTION ? ['./src/index.js'] : 
    [ 
        './src/index.js', 
        'webpack/hot/dev-server',//开启热重载 hot 
        'webpack-dev-server/client?http://localhost:8080' 
        //添加webpack-dev-server客户端 
    ]; 
    var plugins=PRODUCTION ? [] : 
        [ 
            new webpack.HotModuleReplacementPlugin()
            //全局开启代码热替换 如果是CLI这里则不用写 
        ]; 
    module.exports={ 
        entry:entry,//入口文件 
        plugins:plugins, 
        output:{ 
            path:path.join(__dirname,'dist'),// 指定打包之后的文件夹 
            publicPath:'/dist/',// 指定资源文件引用的目录 
            filename:'bundle.js'// 指定打包为一个文件 bundle.js 
            } 
    }
    
    

    3.然后分别运行npm run dev 和npm run build。

    Demo6 - babel for es6/es7

    • 安装babel核心模块
    npm install babel-core babel-loader babel-preset-es2015 babel-preset-stage-0 -save-dev
    

    具体各模块的作用:

    "babel-core" //转换器
    "babel-loader" //转换器的加载器
    "babel-preset-es2015" //ES2015转码规则
    "babel-preset-stage-0" //es7支持,ES7不同阶段语法提案的转码规则(共有4个阶段),选装一个stage-0,stage-1,stage-2,stage-3

    
    - 在项目文件添加.babelrc文件,加入转码规则
    
    ```json
    { "presets":["es2015","stage-0"]}
    
    • 修改webpack.config.js文件,添加module rules模块设置
    ...
    
    module: { 
        rules:[ 
            { 
                test: /\.js$/, 
                use: ["babel-loader"], 
                exclude: path.resolve(__dirname, 'node_modules'),
            } 
        ] 
    }
        
    ...
    
    • 在index.js中添加es6格式的方法
    var messages=require('./message');
    var newMessage = ()=>('<p>'+messages.data +' -From '+ messages.event+"</p>");
    var app=document.getElementById('app'); 
    app.innerHTML=newMessage(); 
    
    if(module.hot){//启用热重载 
        module.hot.accept();
    }
    
    • 运行npm run dev测试,可修改数据验证程序。

    Demo7 - File Loader for Image

    • webpack.config.js的添加devtool:'source-map' ,用于在打包代码的同时生成一个sourcemap文件,并在打包文件的末尾添加//# souceURL,注释会告诉JS引擎原始文件位置

    • 在src目录内新建img文件夹,复制二张图片进来供测试用。这里使用的一张名为s1.png的小图片,大小为9k。另一张名为s2.jpg,大小191k。

    • 在src目录内新建Icon.js文件

    const icon=require('./img/s1.png'); 
    const Image=`![](${icon})`; 
    export default Image;
    
    • 在src目录内新建Img.js文件
    const img=require('./img/s2.jpg'); 
    const Image=`![](${img})`; 
    export default Image;
    
    • 安装文件加载器
    npm install file-loader –-save-dev
    
    • 修改webpack.config.js文件,添加file-loader加载器
    ... 
    module: { 
        rules:[ 
            { 
                test: /\.js$/, 
                use: ["babel-loader"], 
                exclude: path.resolve(__dirname, 'node_modules'),
            },
            {
                test: /\.(jpe?g|png)$/,
                use: ['file-loader']
            },
        ] 
    },
    ...
    
    • 修改index.js,通过import加载图片到页面
    import icon from './Icon'; 
    import img from './Img'; 
    
    
    var messages=require('./message');
    var newMessage = ()=>('<p>'+messages.data +' -From '+ messages.event+"</p>");
    var newMessage2=()=>(
        `<p>${icon} ${img}</p>`
    ); 
    
    var app=document.getElementById('app'); 
    app.innerHTML=newMessage(); 
    app.innerHTML+=newMessage2();
    
    if(module.hot){//启用热重载 
        module.hot.accept();
    }
    

    Demo8 - URL Loader for Images

    使用URL Loader加载图片,limit参数可以使用base64将小图片内联在代码中,减少http请求。

    • 安装url-loader
    npm install url-loader –-save-dev
    
    • 修改webpack.config.js,将图片的loaders改为url-loader?limit=10000&name=images/[hash:12].[ext],小于10k的图片将会以base64的形式内联在代码中,并且图片打包到images文件内,以哈希值命名。
    ...
    module: { 
        rules:[ 
            { 
                test: /\.js$/, 
                use: ["babel-loader"], 
                exclude: path.resolve(__dirname, 'node_modules'),
            },
            {
                test: /\.(jpe?g|png)$/,
                use: ['url-loader?limit=10000&name=images/[hash:12].[ext]']
            },
        ] 
    },
    ...
    

    3.输入npm run dev测试,可以看到s1.png已经被base64内联。s2.jpg文件名称也变成了hash名称。

    Demo9 - Add Button

    • 在src文件目录新建button.js
    const Button={ 
    button:'<button id="myButton">Press me</button>', 
    attachEl:()=>{ 
    document.getElementById('myButton').addEventListener('click',()=>{ 
    // debugger; 
    console.log('clicked'); 
    }) 
    }}; 
    export default Button;
    
    • 修改webpack.config.js,添加dev-tool:’sourse-map’,打包代码的同时生成一个sourcemap文件。
    ... 
    module.exports={ 
        entry:entry,//入口文件
        devtool:'source-map',//打包代码的同时生成一个sourcemap文件,并在打包文件的末尾添加souceURL注释,注释会告诉JS引擎原始文件位置 
        module: { 
            rules:[ 
                { 
                    test: /\.js$/, 
                    use: ["babel-loader"], 
                    exclude: path.resolve(__dirname, 'node_modules'),
                }
            ] 
        }, 
    ... 
    
    • 修改index.js文件,加载button模块并实例化。
    import Button from './button'; 
    var newMessage=()=>(Button.button); 
    var app=document.getElementById('app'); 
    app.innerHTML=newMessage(); 
    Button.attachEl(); 
    
    if(module.hot){
        module.hot.accept(); 
    } 
    
    • 运行测试,点击页面中的按钮,可以看到控制台输出了测试文字

    Demo10 - compress source code

    • 修改webpack.config.js里的plugins变量,添加生产模式时加载插件。
    var plugins = PRODUCTION ? [ 
        new webpack.optimize.UglifyJsPlugin(/*{//代码压缩 
            comments:true,//显示注释 
            mangle:false,//取消代码混淆 
            compress:{ 
                warnings:true//在UglifyJs删除没有用到的代码时不输出警告 
            } 
        }*/) 
        ] : [ 
                new webpack.HotModuleReplacementPlugin()//全局开启代码热替换 如果是CLI这里则不用写 
            ]; 
    plugins.push( 
        new webpack.DefinePlugin({ 
            DEVELOPMENT:JSON.stringify(DEVELOPMENT), 
            PRODUCTION:JSON.stringify(PRODUCTION) 
        }) 
    );
    
    • 修改index.js,将环境信息输出到页面
    var newMessage = ()=>{
        return `DEV:${DEVELOPMENT.toString()} <br> PRO:${PRODUCTION.toString()}`;
    }
    
    
    var app=document.getElementById('app'); 
    app.innerHTML=newMessage(); 
    
    if(DEVELOPMENT){ 
        if(module.hot){//启用热重载 
            module.hot.accept();
        }
    }
    

    3.分别运行npm run dev 和 npm run build可以看到页面上显示的环境,再查看bundle.js,可以看到代码已经按照设置输出。

    ...
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "rimraf dist && NODE_ENV=production webpack && http-server -p 3000",
    "dev": "NODE_ENV=development node dev-server.js"
    },
    
    ...
    

    4.回到webpack.config.js,把UglifyJsPlugin的参数都去掉,使用默认参数

    var plugins=PRODUCTION ? [ 
        new webpack.optimize.UglifyJsPlugin() 
        ] : [ 
        new webpack.HotModuleReplacementPlugin()//全局开启代码热替换 如果是CLI这里则不用 写 
        ];
    

    5.再次运行npm run build打包,此时bundle.js已经被压缩至最小化。

    Demo 11 - Load CSS

    • 安装css-loader和style-loader:npm install css-loader style-loader -save-dev。
    • css-loader 在js文件里,通过require的方式来引入css
    • style-loader 在html中以style的方式嵌入css

    2.在src目录下,创建style文件夹,并创建一个css文件,这里命名为:globalStyle.css

    body{ 
        background:#ddd; 
    }
    
    :local(.box){ 
        background-color:#ff0; 
        padding:1em; 
        border:1px solid #000; 
    }
    
    

    3.在webpack.config.js添加css的loader,webpack的loader的配置是从右往左的,就是先使用css-loader之后使用style-loader

    ... 
    module: { 
        rules:[ 
            { 
                test: /\.js$/, 
                use: ["babel-loader"], 
                exclude: path.resolve(__dirname, 'node_modules'),
            },
            {
                test: /\.css$/, 
                loaders: ["style-loader","css-loader"], 
                exclude: path.resolve(__dirname, 'node_modules'),
            }
    
        ] 
    },
    ...
     
    
    • 修改index.js,引入css文件,并将相应的class添加进页面。
    var style=require('./style/globalStyle.css'); 
    const newMessage=()=>(
    `<div class="${style.box}">    
        DEV:${DEVELOPMENT.toString()}<br>    
        PRO:${PRODUCTION.toString()}<br>    
    </div>`
    
    var app=document.getElementById(‘app’); 
    app.innerHTML=newMessage(); 
    
    if(DEVELOPMENT){ 
        if(module.hot){//启用热重载 
            module.hot.accept(); 
        } 
    }
    
    
    • 测试页面,可以看到页面的样式已经更新,查看源码,原本div的classs为box的,已经被hash名称所代替。hash名称可以在webpack.config.js里css的加载器里自定义
    ...
    test: /\.css$/, 
    use: ["style-loader","css-loader?localIdentName=[path][name]--[local]"], 
    ...
    
    • 当需要将生产环境和开发环境命名进行区分时,可以写在一个变量或常量里
    ... 
    const cssIdentifier=PRODUCTION? '[hash:base64:10]' : '[path][name]---[local]'; 
    ...
    ...
    use: ["style-loader","css-loader?localIdentName=" + cssIdentifier], 
    ...
    ...
    

    查看页面源码时,可以看到webpack打包时,是把样式文件以style的方式嵌在head里的

    Demo12 - CSS Load Seprate

    • 安装插件用于将css样式打包成独立的文件。
    npm install extract-text-webpack-plugin -save-dev
    
    • 需求是在开发环境样式还是嵌在页面上不变,只在打包到生产环境时,才单独打包到一个叫style.css的文件里,因此webpack.config.js里,先引入extract-text-webpack-plugin插件,然后在插件栏设置打包时的名称以及提取css加载时的路径
    ...
    var ExtractTextPlugin = require('extract-text-webpack-plugin');
    var DEVELOPMENT=process.env.NODE_ENV==='development'; 
    var PRODUCTION=process.env.NODE_ENV==='production'; 
    
    var entry=PRODUCTION ? ['./src/index.js'] : [ 
        './src/index.js', 
        'webpack/hot/dev-server',//开启热重载 hot 
        'webpack-dev-server/client?http://localhost:8080'//添加webpack-dev-server客户端 
    ]; 
    var plugins = PRODUCTION ? [ 
        new webpack.optimize.UglifyJsPlugin(),
        new ExtractTextPlugin('style.css'),
        ] : 
        [ 
            new webpack.HotModuleReplacementPlugin()//全局开启代码热替换 如果是CLI这里则不用写 
        ]; 
    plugins.push( 
        new webpack.DefinePlugin({ 
            DEVELOPMENT:JSON.stringify(DEVELOPMENT), 
            PRODUCTION:JSON.stringify(PRODUCTION) 
        }) 
    );
    
    const cssIdentifier=PRODUCTION? '[hash:base64:10]' : '[path][name]--[local]'; 
    
    const cssLoader=PRODUCTION ? ExtractTextPlugin.extract('css-loader?localIdentName=' + cssIdentifier) : 
        ['style-loader','css-loader?localIdentName=' + cssIdentifier];
    
    module.exports={ 
        entry:entry,//入口文件
        module: { 
            rules:[ 
                { 
                    test: /\.js$/, 
                    use: ["babel-loader"], 
                    exclude: path.resolve(__dirname, 'node_modules'),
                },
                {
                    test: /\.css$/, 
                    //use: ["style-loader","css-loader"], 
                    use: cssLoader, 
                    exclude: path.resolve(__dirname, 'node_modules'),
                }
    
            ] 
        }, 
    ...
    
    • index.html页面要单独加载打包生成的样式文件style.css
    <link rel="stylesheet" href="./dist/style.css">
    
    • 然后运行运行npm run build 查看,此时style.css是单独生成的。

    • style.css的名称也可以用hash表示

    new ExtractTextPlugin( 
    'style-[contenthash:10].css'//根据内容生成hash值 
    ,{allChunks: true}//所有分离文件的样式也会全部压缩到一个文件上 
    )
    

    Demo13 - HTML Template

    • 安装模板插件
    npm install html-webpack-plugin -save-dev
    

    2.创建html模版:index-template.html

    <!DOCTYPE html>
    <head>    
    <title></title>    
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>    
    <div id="app"></div>
    </body>
    </html>
    
    • webpack.config.js顶部导入模版插件
    var HTMLWebpackPlugin=require('html-webpack-plugin');
    
    • 在plugins处实例化,并将模版文件设置为index-template.html
    var plugins=PRODUCTION ? [ 
        new webpack.optimize.UglifyJsPlugin(), 
        new ExtractTextPlugin( 
            'style-[contenthash:10].css'//根据内容生成hash值 
        ), 
        new HTMLWebpackPlugin({// webpack 指定目录(package内设置)生成静态HTML文件 
        template:'index-template.html' 
        }) 
    ] : [ 
    new webpack.HotModuleReplacementPlugin()//全局开启代码热替换 如果是CLI这里则不用写
    
    • 静态文件在dist内生成名为index.html的文件,其他资源路径将和开发环境不同,所以需要设置区分判断。
    output:{ 
    path:path.join(__dirname,'dist'),// 指定打包之后的文件夹 
    publicPath: PRODUCTION ? '/' : '/dist/', 
    filename: PRODUCTION ? 'bundle.[hash:12].min.js' : 'bundle.js'// 指定打包为一个文件 bundle.js 
    }
    
    • 修改package.json,运行npm run build打包测试。
    ...
    "scripts": {
        "build": "rimraf dist && NODE_ENV=production webpack && http-server ./dist -p 3000 ",
        "dev": "NODE_ENV=development node dev-server.js"
      },
    
    ...
    

    demo14 - Tabs Pages

    • 在src文件内新建page1.js
    const page=`<h1>页面1</h1>`;
    export default page;
    
    
    • 在src文件内新建page2.js
    const page=`<h1>页面2</h1>`;
    export default page;
    
    • 修改index.js,创建两个按钮,并添加相应的点击事件,事件触发时使用System导入页面并将页面的的内容复制到content内。
    var app=document.getElementById('app');
    app.innerHTML=`    
        <div id="menu">        
            <button id="loadPage1">Load1</button>        
            <button id="loadPage2">Load2</button>    
        </div>    
        <div id="content">        
            <h1>home</h1>    
        </div>`;
    document.getElementById('loadPage1').addEventListener('click',()=>{
    //System.import 会令每个可能的模块都产生一个独立的块(chunk)。    
    System.import('./page1').then(pageModule=>{        
        document.getElementById('content').innerHTML=pageModule.default;    
    })
    });
    document.getElementById('loadPage2').addEventListener('click',()=>{    
    System.import('./page2').then(pageModule=>{        
        document.getElementById('content').innerHTML=pageModule.default;    
    })
    });
    
    if(DEVELOPMENT){    
        if(module.hot){//启用热重载       
            module.hot.accept();    
    }}
    
    • 运行npm ren dev测试,在这之前,别忘记把index.html引用css和js的路径改回来
    • 打开浏览器的network,来回点击按钮1和按钮2,观察network加载的内容,可以发现,0.bandle.js和1.bandle.js是异步加载,并且不会被重复加载。

    Demo15 - Jquery

    • 安装jquery插件
    npm install jquery –-save-dev
    
    • 在index.js中导入jquery,并创建一个jquery实例
    import $ from 'jquery'; 
    $('#app').css('background','#ff0');
    
    • 运行测试时,app背景已经发生改变。运行打包后,jquery也被打包进了bundle.js,这并不是我们想要的。而且,jquery并非全局,仅可在index.js使用,想要将jquery加载为全局模块,需要在webpack.config.js中设置externals
    ... 
    module.exports={ 
        externals:{ 
            'jquery':'jQuery' 
        }, 
    devtool:'source-map', 
    entry:entry,//入口文件 
    plugins:plugins, 
    ... 
    
    • 然后jquery需要从外部加载进来,分别添加到index.htmlindex-template.html的head中,建议使用网上的jquery的CDN。如:
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    
    • 分别运行开发环境和生产环境查看,jquery从外部加载,没有被打包进bundle.js。

    相关文章

      网友评论

        本文标题:一步一步学WebPack 2

        本文链接:https://www.haomeiwen.com/subject/diltcxtx.html