zoukankan      html  css  js  c++  java
  • webpack

    1、什么是webpack

    Webpack是前端一个工具,可以让各个模块进行加载,预处理,再进行打包。现代的前端开发很多环境都依赖webpack构建,比如vue官方就推荐使用webpack。

    2、简单使用下webpack

    2.1、首先我在 c 盘下新建一个webpack-demo1的文件夹,然后命令行进入该目录,执行 npm init --yes 项目初始化,该命令会在文件下生成一个package.json文件,该命令也可以是 npm init ,这样的话它会询问你一系列诸如项目名称,项目描述,作者等信息,如果你不准备在npm中发布你的模块,这些问题的答案都不重要,一路回车默认即可。package.json如下:

    {
      "name": "webpack-demo1",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }

    接下来在该环境中安装一下3.5.6版本webpack,命令 npm install webpack@3.5.6 --save-dev,接下来再全局安装一下,npm install webpack@3.5.6 -g,安装成功之后,package.json文件会出现webpack的版本信息:

    {
      "name": "webpack-demo1",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "webpack": "^3.5.6"
      }
    }

    实现打包功能:

    打包一个js文件

    在根目录下新建一个index.js,和index.html文件,index.js文件内容:

    function say(){
        alert("hello webpack");
    }
    say();

    输入命令:webpack index.js index.bundle.js,该命令含义:

    #webpack {entry file} {destination for bundled file}

    # {extry file}出填写入口文件的路径,本文中就是上述main.js的路径,

    # {destination for bundled file}处填写打包文件的存放路径

    # 填写路径的时候不用添加{}

    结果自动生成了一个 index.bundle.js 的文件,我们可以在index.html中引入,在浏览器中顺利弹出 “hello webpack”

    打包多个文件:

    在根目录下又新建一个calc.js文件,内容:

    function add(a,b){
        return a+b;
    }
    module.exports = {    //导出这个模块
        add: add
    }

    把index.js文件内容更改:

    var oCalc = require("./calc");   //引入模块
    function say(){
        alert("hello webpack");
    }
    say();
    alert(oCalc.add(10,20));    //使用该模块的功能

    执行打包:webpack index.js index.bundle.js,成功后,打开index.html,弹出俩次 1、“hello webpack”   2、“30”

    webpack打包,后面可以跟很多参数:

    • --progress: 打包进度
    • --display-modules: 打包的模块
    • --colors: 是否彩色显示 打包提示信息
    • --display-reasons: 打包原因
    • --watch: 自动监控文件变化

    比如我使用 --watch:webpack index.js index.bundle.js --watch,这样的话会自动监测,只要与index.js相关的文件发生了变化,自动打包。

    webpack.config.js

    Webpack拥有很多其它的比较高级的功能(比如说本文后面会介绍的loadersplugins),这些功能其实都可以通过命令行模式实现,但是正如前面提到的,这样不太方便且容易出错的,更好的办法是定义一个配置文件,这个配置文件其实也是一个简单的JavaScript模块,我们可以把所有的与打包相关的信息放在里面。演示,新建一个基本目录结构webpack-demo2如图:

    其中main.js文件随便写一些内容:

    function say(){
        alert("今天是星期五");
    }
    say();

    接下来,配置一下webpack.config.js文件:

    module.exports = {
        entry: "./src/js/main.js",
        output: {
            path: __dirname + "/dist/",
            filename: "js/index.bundle.js"
        }      
    }    

    这里参数做一下解释,entry就是入口,项目被运行时,第一个被查找的文件,output就是出口,path是输出路径,要使用绝对路径,__dirname是当前文件的绝对路径,“E:webpack-demo2srcjs”,filename是输出文件的文件名,可以在前面加上路径,稍后它会自动生成该路径,配置好之后,进行打包,命令行:webpack(这里不用再写后面的俩个参数了,因为我们已经在webpack.config.js里已经配置好了),成功后依照我们配置好的路径,在dist/js目录下,生成了index.bundle.js文件

    在index.html中引入该文件,然后运行,顺利弹出“今天是星期五”

    我们还可以通过package.json文件的scripts部分,简化打包操作:

    比如我们进行打包时后面跟着的几个参数(上面有说),我们可以在package.json里配置下:

    "dev" : "webpack --config webpack.dev.config.js --progress --display-modules --colors --display-reasons"

    这样的话我们在执行打包时直接命令:npm run dev 就会执行相应的打包,后面几个参数也会生效。简化了操作。

    我们上面是打包一个js文件,如果想打包多个文件呢,这里有俩种情况:

    1、多个文件打包成一个文件,这里要用数组配置entry了,比如,我们在main.js同目录下新建一个calc.js文件,内容:

    function add(a,b) {
        alert(a + b);
    }
    add(10,20);

    把webpack.config.js文件内容更新为:

    module.exports = {
        entry: ["./src/js/main.js","./src/js/calc.js"],   //entry用数组配置
        output: {
            path: __dirname + "/dist/",
            filename: "js/index.bundle.js"
        }
    }

    执行打包后成功将俩个文件打包在dist/js.index.bundle.js,预览index.js,弹出俩次 “今天是星期五” “30”

    2、多个文件打包成多个文件,这里entry要采用字面量(json)方式配置

    module.exports = {
        entry: {
            main: "./src/js/main.js",
            calc: "./src/js/calc.js"
        },
        output: {
            path: __dirname + "/dist/",
            filename: "js/[name].bundle.js"   //filename支持多种动态起名字的方式( id, name, hash, chunkhash, query ) name就是entry里写的文件的名字
        }
    }

    执行打包,成功在dist/js里生成俩个文件

    html-webpack-plugin插件的使用

    我们打包后的js文件,默认不会自动插入到模板文件中的,我们可以安装html-webpack-plugin插件,先安装这个插件 npm install html-webpack-plugin --save-dev,接下来在webpack.config.js中引入并配置一下:

    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
        entry: {
            main: "./src/js/main.js",
            calc: "./src/js/calc.js"
        },
        output: {
            path: __dirname + "/dist/",
            filename: "js/[name].bundle.js"   //filename支持多种动态起名字的方式( id, name, hash, chunkhash, query ) name就是entry里写的文件的名字
        },
        plugins: [new HtmlWebpackPlugin()]
    }

    弄好之后,执行打包,与之前不同的是这次直接在dist目录下生成了index.html文件,该html文件自动引入了打包后的俩个js文件。

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>Webpack App</title>
      </head>
      <body>
      <script type="text/javascript" src="js/main.bundle.js"></script><script type="text/javascript" src="js/calc.bundle.js"></script></body>
    </html>

    但是有一个问题,我们在根目录下本来就建好了一个html文件,这次重新生成的文件和之前的没有任何的联系,我们需要让生成的html文件内容参照原有html文件。重新配置下webpack.config.js。

     plugins: [new HtmlWebpackPlugin(
            {
                template : './index.html'
            }
     )]

    这次打包的话,就是参照原模板html文件,进行生成了。并自动引入了js文件。

    插件的其他配置选项:

    filename:打包生成的文件名,还可以加目录,默认没有写的时候是index.html

    inject:有4个值:

    •  true  引入js文件
    • 'head'   把js引入放在head标签里面
    • 'body'   把js引入放在body标签里面
    • false   不引入js文件

    举栗:重新配置下webpack.config.js文件中的plugins:

    plugins: [new HtmlWebpackPlugin(
         {
            template : './index.html',
             filename : 'index-bundle.html',
             inject : 'head'
         }
     )]

    然后打包,这次在dist目录下生成的html文件名为index.bundle.html,并且自动引入的js文件在head标签内。

    插件的另一个选项title,就是设置一个标题,用法如下,webpack.config.js文件中的plugins:

    plugins: [new HtmlWebpackPlugin(
            {
                template : './index.html',
                filename : 'index-bundle.html',
                inject : 'head',
                title: 'hello webpack~'
            }
    )]

     接下来在原html文件中的title标签内写入:

    <title><%= htmlWebpackPlugin.options.title %></title>

    现在打包后的html文件的标题为 “hello webpack~”

    html-webpack-plugin插件中的options除了自己定义了一些基本配置外,我们是可以任意的添加自定义的数据:

    plugins: [
        new HtmlWebpackPlugin({
            template : './index.html',
            title : 'hello webpack',
            inject : true,
            date : new Date(),
            userName : '张三',
            age : 22
        })
    ]

    在原始模板html文件中读取:

    <h3><%= htmlWebpackPlugin.options.date %></h3>
    <h3><%= htmlWebpackPlugin.options.userName %></h3>
    <h3><%= htmlWebpackPlugin.options.age %></h3>

    这样的话,在生成的html文件中就会添加相应的数据。

    minify选项,压缩html文件:

    new HtmlWebpackPlugin({
         template : './index.html',
         title : 'ghostwu教你学webpack',
         inject : false,
         minify : {
             removeComments : true, //去掉注释
             collapseWhitespace : true, //去掉空行
         }
     })

    再次打包,这次html文件都被压缩。

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>我是原有的模板文件~</body></html>

    chunks选项

    这个属性非常有用,可以指定某个页面加载哪些chunk( 可以简单的把他理解成js文件 ),我们可以用他做多个页面模板的生成. 比如,我们在实际开发中,做一个博客网站,一般来说有首页,文章列表页,文章详情页等等,这些页面都有一个特点,都要引入一些公共的js文件以及该页面特有的js文件,比如:

    • 首页( index.html )                  引入 main.js, index.js
    • 文章列表页( list.html )           引入 main.js, list.js
    • 文章详情页( detail.html )       引入 main.js, detail.js

    传统方式,一个个的打开文件,拷贝修改,如果后期维护,又是一堆文件中,查找,拷贝,修改。很容易出错,而且效率低下,可以用webpack解决,

    我们先在src/js中创建对应js,然后webpack.config.js配置:

    var HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
        entry : {
            main : './src/js/main.js',
            index : './src/js/index.js',
            list : './src/js/list.js',
            detail : './src/js/detail.js'
        },
        output : {
            //__dirname,就是当前webpack.config.js文件所在的绝对路径
            path : __dirname + '/dist', //输出路径,要用绝对路径
            filename : 'js/[name].bundle.js', //打包之后输出的文件名
        },
        plugins: [
            new HtmlWebpackPlugin({
                template : './index.html',
                title : '博客首页-',
                filename : 'index.html',
                inject : true,
                chunks : ['main', 'index']
            }),
            new HtmlWebpackPlugin({
                template : './index.html',
                title : '列表页-',
                filename : 'list.html',
                inject : true,
                chunks : ['main', 'list']
            }),
            new HtmlWebpackPlugin({
                template : './index.html',
                title : '文章详情页-',
                filename : 'detail.html',
                inject : true,
                chunks : ['main', 'detail']
            })
        ]
    };

    执行打包,成功之后,会在dist目录下生成3个html文件,并且在引入main.js的同时,各自引入属于自己的js。

    loader 

    官方解释为文件的预处理器,通俗点说webpack在处理静态资源的时候,需要加载各种loader,比如,html文件,要用html-loader,要让js识别css文件要用css-loader,让文件在页面中生效要用style-loader等等.

    babel-loader的作用---打包时把es6语法转为浏览器认识的es5语法,用法:

    先建一个webpack-demo3的基本机构

    需要安装的插件等:
    1,npm init --yes( 初始化项目的package.json )
    2,npm install webpack@3.5.6 -g ( 全局安装webapck )
    3,npm install webpack@3.5.6 --save-dev (局部安装webpack )
    4,npm install html-webpack-plugin --save-dev ( 安装html-webpack-plugin插件 )

    webpack.config.js文件:

    var htmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
        entry : './src/main.js',
        output : {
            path : __dirname + '/dist',
            filename : 'js/[name].bundle.js',
        },
        plugins : [
            new htmlWebpackPlugin({
                filename : 'index.html',
                template : 'index.html',
                inject : true
            })
        ]
    }

    modal.js文件

    let modal = function(){
        return {
            'component-name' : 'modal'
        }
    }
    export default modal;

    main.js文件

    import modal from './components/modal.js';
    let App = function(){
        console.log( '项目入口文件main.js' );
    }
    new App();

    进行打包,然后查看dist/js/下的main.bundle.js文件,发现是引入了es6的语法,这样的话浏览器是不认识的,我们可以在打包之前用babel.loader解决。

    安装babel-loader:npm install --save-dev babel-loader babel-core babel-preset-env webpack

    配置一下babel-loader:

    var htmlWebpackPlugin = require('html-webpack-plugin');
    let path = require('path');
    module.exports = {
        entry: './src/main.js',
        output: {
            path: __dirname + '/dist',
            filename: 'js/[name].bundle.js',
        },
        plugins: [
            new htmlWebpackPlugin({
                filename: 'index.html',
                template: 'index.html',
                inject: true
            })
        ],
        module: {
            rules: [
                {
                    test: /.js$/,
                    exclude: /(node_modules)/,
                    include: [
                        path.resolve(__dirname, "src"),
                    ],
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['env']
                        }
                    }
                }
            ]
        }
    }

    rules就是配置规则,他是一个数组,每一项为一个对象,如果有多个loader,那就用多个对象,

    test: /.js$/ 就是以.js结尾的文件,exclude:排除node_modules这个目录,意思就是不要去这个目录下处理.js的文件,有什么好处呢?大大提高打包的速度. include里面的配置意思就是把src目录下面的js文件作为处理的目标,

    use配置就是使用babel-loader

    再进行打包,成功之后查看打包后生成的main.bundle.js文件中,发现已经转成es5语法了。

    var App = function App() {
        console.log('项目入口文件main.js');
    };
    new App();

    css-loader style-loader

    在src目录下建一个css目录,里面有一个sytle.css文件,

    body{
        background-color: bisque;
    }

    在main.js中导入css文件

    import modal from './components/modal.js';
    import './css/style.css';
    let App = function(){
        console.log( '项目入口文件main.js' );
    }
    new App();

    执行打包,会报错 “你可能需要一个loader来处理这个文件类型”,我们可以安装对应loader解决,npm install css-loader style-loader --save-dev,安装完之后,配置一下webpack.config.js:

    var htmlWebpackPlugin = require('html-webpack-plugin');
    let path = require('path');
    module.exports = {
        entry: './src/main.js',
        output: {
            path: __dirname + '/dist',
            filename: 'js/[name].bundle.js',
        },
        plugins: [
            new htmlWebpackPlugin({
                filename: 'index.html',
                template: 'index.html',
                inject: true
            })
        ],
        module: {
            rules: [
                {
                    test: /.js$/,
                    exclude: /(node_modules)/,
                    include: [
                        path.resolve(__dirname, "src"),
                    ],
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['env']
                        }
                    }
                },
                {
                    test: /.css$/,
                    exclude: /(node_modules)/,
                    use: [
                        'style-loader',
                        'css-loader'
                    ]
                }
            ]
        }
    }
    执行webpack打包,就能看到css内嵌到main.bundle.js中了,css-loader是处理css文件,style-loader是把css内嵌到浏览器。

    less-loader 首先在src/css/里建一个less.less,内容:
    @w:200px;
    @h:200px;
    *{
      margin: 0;
      padding: 0;
    }
    #box{
      div{
        width:@w;
        height:@h;
      }
    }
    在main.js中引入,打包,直接报错,我们可以安装一个less-loader来解决,安装,npm install --save-dev less-loader less,一样的,配置一下webpack.config.js:
    {
        test: /.less$/,
        use: [
            {
               loader: "style-loader"  //最后交由style-loader处理
            }, {
               loader: "css-loader"  //然后交给css-loader处理,
            }, {
               loader: "less-loader"     //当碰到less文件时,交给less-loader处理,
            }
        ]
    }

    现在打包的话,less文件就被嵌入进去了。

    html-loader

    如果想把html内容引入的话就需要html-loader了,在src/components目录下新建一个modal.html,内容:

    <div class="modal">
        <div class="modal-heading">模态框头部 - by ghostwu</div>
        <div class="modal-body">模态框内容部分 - by ghostwu</div>
    </div>

    这次就不错误示范了,直接安装html-loader,npm install html-loader --save-dev,然后配置一下webpack.config.js:

    {
         test: /.(html)$/,
         use: {
           loader: 'html-loader',
         }
    }

    modal.js文件引入modal.html

    import tpl from './modal.html';
    let modal = function(){
        return {
            'component-name' : 'modal',
            'tpl' : tpl
        }
    }
    export default modal;

    main.js对webpack_demo3目录下的index.html文件插入模板(modal.html)

    import modal from './components/modal.js';
    let App = function(){
        var oApp = document.querySelector("#app");
        var oModal = new modal();
        oApp.innerHTML = oModal.tpl;
    }
    new App();

    在index.html模板文件中建一个id为app的div,打包,

    这次在dist目录下生成的index文件中,就有了modal.html的内容。

    file-loader

    图片资源的打包,图片在静态排版中,经常出现的两个位置1,css通过background引入背景,2,还有一种就是在html模板文件中用img标签引入的方式,如果要在webpack使用图片资源,我们需要用file-loader来处理.如果不使用的话,就会报错。

    安装,安装 npm install file-loader --save-dev,配置:

    {
         test: /.(png|gif|jpg|svg|jpeg)$/i,
         use: {
             loader: 'file-loader',
             query : {
                 name : 'assets/[hash].[ext]'
             }
         }
    }

    query部分的配置,是为打包的图片设置一个自定义的存储路径和文件名称
    注意:在模板中引入图片路径,
    如果是相对路径要这样引入${require(图片的相对路径)},否则打包路径会出现问题

    <img src="${ require('../img/dm.jpg') }" alt="">

  • 相关阅读:
    String、StringBuilder、StringBuffer区别
    深拷贝和浅拷贝
    二叉查找树(一)
    二叉树的遍历
    二叉树
    递归
    队列

    数据结构基础
    视图
  • 原文地址:https://www.cnblogs.com/xlj-code/p/9241183.html
Copyright © 2011-2022 走看看