Webpack 2.0 学习与总结

webpack 2.0 用了小一个月了,一直都是照猫画虎。这俩天开始细读官网的部分文章结合一些讲解视频,深入学习一下。小结一发来汇总知识点。

webpack 的由来?
  已存在的模块打包器对于大型应用(大型的SPA)来说并不适合。发展另一个模块打包器最迫切的原因那就是代码分割(Code Splitting)并且可以让静态资源能够无缝的适用于模块化。
webpack 可以做的事情?
  将项目间的依赖分割成代码块并按需加载
  将初始化载入时间保持在最低
  每一个静态资源都应被作为一个模块
  有将第三方的库整合为模块的能力
  有定制模块的能力
  适合大型的单页应用
webpack 的特点有?
  代码分割:webapck 在它的依赖树中有俩种依赖关系,同步与异步!异步依赖可以分割成许多不同的点(部分)并且这些依赖来自于新的代码块。在块级树生效后,一个文件会被传递给每一个代码块。
  加载器:webpack 是唯一的与生俱来就具有处理 JS 代码的能力,但是加载器被用来将其他源文件转换为 JS 文件。这样来做我们就可以处理来自不同模块的源文件。
  智能解析:webpack 可以智能解析第三方库文件。它甚至允许在依赖中出现解释性的描述例如:require("./templates/" + name + ".jade")。具有 CMD&AMD&es6 三种处理模式。
  插件系统:webpack 最有特点的就是它生态丰富的插件系统。许多内部的特性都建立在这个插件系统之上。它允许你定制你自己的需求并且可以将其开源。

以上是我对 what-is-webpack 的翻译,这样我们对 webpack 有了大体的了解。总所周知对于自动化构建这部分来说,我们可以使用的工具很多,比如:grunt 、gulp 等,那么这俩者与 webpack 有什么区别呢?
  Grunt&Gulp 是流程工具,其工作方式是在一个配置文件中,指明对某些文件进行的操作(诸如编译,组合,压缩等任务)的具体步骤,之后可以自动完成这些任务。流程如下:

Webpack 2.0 学习与总结_第1张图片
Grunt&Gulp.png

  WebPack则是一个模块打包器,其工作方式通过主文件(index.js)找到全部依赖(自己设置的代码块、第三方库等)使用loaders 处理,最终打包为可执行的
Javascript 文件。流程如下:
Webpack 2.0 学习与总结_第2张图片
WebPack.png

下面通过实例来看看 webpack 的威力。
1> 简单使用

mkdir webpack-1
cd webpack-1
npm init
npm install -d webpack --save-dev

安装完 webpack 2.0 后,新建 js&html&css 文件我得目录如下:


Webpack 2.0 学习与总结_第3张图片
webpack-1-1.png

hello.js 中的代码如下:

require('./world.js');
require('./style.css');

function hello () {
  alert('test!');
}

hello();

style.css 中的代码如下:

html , body{
    padding: 0;
    margin: 0;
}
body{
    background-color: red;
}

在 webpack 能做的事情中我们了解到 webpack 具有识别 js 的能力,那
css 呢?答案是不能!那怎么解决呢?利用 loaders 来处理。对于 css 文件我们使用 css-loader&style-loader 先利用 npm 分别安装。之后在当前目录下打开 cmd 键入以下命令:webpack hello.js hello.bundle.js --module-bind css=style-loader!css-loader --watch module-bind 命令用于启用 loader 处理主文件,watch 用来监视 hello.js 文件的变化,若变化则自动更新 hello.bundle.js 文件。

在项目中我们如果每次都要敲一长串命令的话很麻烦,我们只需要在package.json 的 script 中配上 webpack 命令。我得配置如下: "webpack": "webpack --config webpack.config.js --progress --display-modules --colors --display-reasons" 其中 progress&modules&reasons分别代表过程百分比 / 各模块 / 打包原因。

我们可以将webpack的配置单独放在一个配置文件(webpack.config.js)中会自动读取该文件,如果该文件不存在或者名称不一致则需要通过命令行来运行(不存在的话通过 webpack 命令,名称不一致通过--config 来指定文件)。

对于 webpack 来说入口与出口肯定是必不可少的,那么在配置文件中我们这样写:

module.exports = {
    entry: './src/index.js',   // entry: ['./src/index-1.js' , './src/index-2.js'] 多入口
    output: {                        //配置文件输出位置
      filename: 'bundle.js',
      path: './dist/js'  
    }
};

还有 entry 传入对象的形式入口:

module.exports = {
    entry:{
        main1: './src/index1.js',
        main2: './src/index2.js'
    },
    output: {                        //配置文件输出位置
        filename: '[name]-[chunkhash].js',  // 这里如果还这样写filename: 'bundle.js'的结果是index2会把index1覆盖,所以我们利用内置的占位符 name & chunkhash 来命名
        path: './dist/js'  
    }
};

这样的话在 index.html中引入的 js 文件名我们不可能每次打包完都要手动修改,这样很麻烦。所以我们需要使用插件来自动帮我们设置。npm install html-webpack-plugin安装后修改配置文件为:

var htmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        main: './src/scripts/main.js',
        mainA: './src/scripts/mainA.js'
    },
    output: {                        //配置文件输出位置
        filename: '[name]-[chunkhash]-bundle.js'        //打包的文件名称*/
        path : './dist',
        filename: 'js/[name]-[chunkhash].js',            //把html与js分开存放
        publicPath: 'http://bluespace/'                  //上线地址的绝对路径,自动替换当前项目中相对路径
    },
    plugins: [
        new htmlWebpackPlugin({
            //filename: '[hash].index.html',              //名称
            template: 'index.html',                     //以什么为模板,一般以配置文件下的index.html为模板
            //inject: 'head'                                //scripts存放的位置
            title: 'webpack is good!',
            inject: false,
            date: new Date(),
            minify: {                                    //压缩html文件,去除空格,去除注释
                collapseWhitespace: true,
                removeComments: true            
            }
        })
    ]
    
};

而 index.html 模板的代码如下(html-webpack-plugin支持ejs写法):



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

2> 利用 htmlwebpackplugin 构建多页应用 (已上传至 github)
3> 配置常见的 loader

var htmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');

    module.exports = {
        entry: './src/app.js',
        output: {
            path: './dist',
            filename: 'js/[name].bundle.js'
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    use: [{
                        loader: 'babel-loader',
                        options: {
                            presets: ['es2015']
                        }
                    }],
                    include: path.resolve(__dirname , './src'),
                    exclude: path.resolve(__dirname , './node_modules')                           //尽量使用绝对路径会提高打包速度在configruation里面通过exclude和include来提高打包速度
                
                },
                {
                    test: /\.css$/,
                    use: [
                        'style-loader',
                        {
                            loader: 'css-loader',
                            options: { importLoaders: 1 } 
                        },
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins: function(){
                                    return [
                                        require('autoprefixer')
                                    ];
                                }
                            }
                        }
                    ]
                },
                {
                    test: /.\.less$/,
                    use: [
                        'style-loader',
                        'css-loader',
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins: function(){
                                    return [
                                        require('autoprefixer')         // postcss下的自动补全浏览器前缀的插件
                                    ];
                                }
                            }
                        },
                        'less-loader'      //使用less或者sass时不用为@import的less/sass添加importLoaders:1因为自动添加。因为less/sass支持import
                    ]
                },
                {
                    test: /\.html$/,
                    use: 'html-loader'      // 将html当做字符串处理,对应innerhtml。坏处是不能使用for等模板语法
                },
                {
                    test: /\.ejs$/,
                    use: 'ejs-loader'       // 把html当做模板处理
                },
                {
                    test: /\.(png|jpg|gif|svg)$/i,            //用包管理工具除了模板外的文件放置相对路径没有问题,但是在模板文件中应该![](${require('../../assets/George.jpg')})
                    use: [
                        {
                            loader: 'url-loader',                       //url-loader可以设置limit若图片体积小于limit的话则通过url-loader转化为base64代码,若大于则调用file-loader
                            options: {
                                name: 'assets/[name]-[hash:5].[ext]',
                                limit: 4000                                         //经常需要加载的图片利用http请求较好,因为可以享受到缓存,而base64则需每次读取
                            }
                        },
                        'image-webpack-loader'                                      //压缩图片体积
                    ]                       
                }
            ]
        },
        plugins: [
            new htmlWebpackPlugin({
                filename: 'index.html',
                template: 'index.html',
                inject: 'body'
            })
        ]
    };

练习代码全部上传至 George's github

参考资料:
webpack
入门webpack,看这篇就够了
html-webpack-plugin

你可能感兴趣的:(Webpack 2.0 学习与总结)