美文网首页
webpack前端自动化构建方案

webpack前端自动化构建方案

作者: 油油011 | 来源:发表于2016-09-04 17:53 被阅读0次

    转载请注明原作者以及链接,谢谢!


    我们项目的框架使用的是angular.js(v1.5.8)+ webpack,使用webpack主要是要想做到以下几点:
    1.抛弃原来项目中的requireJs,gulp/grunt。模块化和打包均由webpack实现。
    2.将项目资源大部分输出到一个bundle.js文件,减少浏览器首次加载时的资源请求数量。
    3.使用npm安装框架依赖。不再引入项目中。避免项目代码提交时更改库代码。
    4.进行代码压缩,并开启nginx的gzip,对代码再次进行压缩。
    5.实现测试和生产环境使用不同的配置文件。
    6.生成带有项目名称和版本号的文件夹并压缩(用于webApp)。
    7.生成带有hash的bundle.js文件。可以解决浏览器因为缓存不刷新的问题(用于web项目)。

    因为项目情况,没有用到es6,scss等。没有进行代码转换。如果需要转码,只要找到对应的loader。npm安装后加载进来就可以了,这里不会提到。另外,webpack我也没用多久。如果哪里写的不好或者写错了,请指点,谢谢!
    先奉上webpack文档地址:webpack


    ▍第一步:搭建环境

    安装node.js和npm

    npm 是 javaScript的包管理工具,类似maven的依赖管理, 用它来下载我们需要的模块。
    Node.js下载地址

    创建package.json

    npm init
    在项目文件夹下新建一个package.json并填写项目信息,项目名称以及版本号等项目信息

    npm安装插件

    全局安装webpack:
    npm install webpack -g
    安装webpack-dev-server:
    npm install webpack-dev-server -g
    安装依赖到项目中并加入package.json
    npm install [package] --save-dev/ npm install [package] --save
    可能有时候会npm安装包比较慢甚至是安装不了,可以使用淘宝NPM镜像[cnpm]
    删除依赖
    npm uninstall [package]

    ▍第二步:编写webpack.config.js文件

    代码:webpack+anuglar.js
    目录结构:
    webpack
    |____app
    | |____index.html
    | |____index.js
    |____package.json
    |____webpack.config.js
    |____zip.js
    
    使用loader加载器对资源进行转换
    module.exports = {
        entry: path.resolve(__dirname, "app", "index.js"),
        output: {
            path: "dist",
            filename: "bundle.[hash].js"
        },
        module: {
            loaders: [
                {
                   test: /\.js$/,
                   exclude: /node_modules/,
                    loader:"ng-annotate"
                }, {
                   test: /\.css$/,
                   loader: "style!css!autoprefixer"
                }, {
                   test: /\.html$/,  
                   exclude: /node_modules/,
                   loader:"html"
                }, {
                   test: /\.(ttf|eot|otf)$/,
                   loader: "file"
                }, {
                   test: /\.woff(2)?$/,
                   loader: "url?limit=8192&minetype=application/font-woff"
                }, {
                   test: /\.(png|jpg|gif|svg)$/,
                   loader: "url?limit=8192&name=images/[name].[ext]"
                }
            ]
        }
    }
    
    entry编译的入口Js文件。ouput文件输出定义

    编译后的文件名bundle.[hash].js,这里用到hash。每一次进行webpack打包,都会生成一个hash值,用它为文件命名,能让每次生成的文件名都不一样。浏览器访问也不会存在缓存问题。path.resolve用来拼接路径,__dirname是指当前路径的绝对路径。

    loader加载器的使用,如css-loader。

    首先安装css-loader:npm install --save-dev css-loader
    在配置文件中,通过正则绑定对应的loader, 可以省略loader,写成css/css-loader均可。使用!可以定义多个loader,?后边配置参数

    ng-annotate-loader是用来处理angular.js的代码。这是一小段代码:
    angular.module('myApp', [])
           .controller('testCtrl',  function ($scope) {});
    

    $scope普通的压缩会把它当成参数压缩了。解决的方法,一种是写成数组

    ['$scope', function($scope) {}];
    // 或者是
    testCtrl.$inject = ['$scope'];
    

    另外一种是使用ng-annotate。编译之后,会自动补全

    angular.module('myApp', [])
           .controller('testCtrl',  ["$scope", function ($scope) {}]);
    
    autoprefixer-loader可以补全css代码
    图片base64编码

    图片这里使用url-loader,会过滤图片。
    limit=8192 : 将图片大小小于8K的转为base64编码。
    name=images/[name].[ext] : 大于8k的图片则存放到dist/images底下。

    webpack sourcemap

    调试的时候可能需要知道这个页面对应了哪些文件。这里就要用到sourcemap。可以使用命令webpack -d去生成,或者在webpack.config.js中配置devtool
    其实调试很多时候主要还是看样式来自哪个文件。所以这里简单一点,如果是测试环境。css-loader文件后边加上sourcemap。这样子编译的文件小,速度也快一些。我有时候配置devtool不起效果。也不知道为什么。
    { test: /\.css$/, loader: "style!css?sourceMap!autoprefixer" }

    生成index.html

    每一次生成的bundle.js文件因为带有hash,所以都是不同的。不能在index.html里边直接引入。这里要用到一个插件html-webpack-plugin根据模板生成index.html页面(github地址)。
    安装:npm install html-webpack-plugin --save-dev
    引入:var HtmlWebpackPlugin = require('html-webpack-plugin');

    module.exports = {
        ...
        plugins: [                                       
            new HtmlWebpackPlugin({        
                filename: path.resolve([输出路径], 'index.html'),
                template: path.resolve([输入路径], "index_template.html")
            })
        ]
    }
    

    在模板index_template.html不需要引入bundle.js。生成index.html会自动引入。

    ▍第三步:编译打包项目工程

    webpack常用指令:
    $ webpack        // 最基本的启动webpack方法
    $ webpack -w     // 提供watch方法,实时进行打包更新
    $ webpack -p     // 对打包后的文件进行压缩
    $ webpack -d     // 提供source map,方便调试。
    
    环境配置(webpack.config.js)
    "scripts": {
      "production": "set NODE_ENV=production && webpack -p",
        "test" : "set NODE_ENV=test && webpack"
    }
    

    执行npm run production / npm run test
    这是以前的做法。通过设置环境变量NODE_ENV来判断打包的环境。在webpack.config.js中通过process.env.NODE_ENV获取这个值。
    发现在mac上是可以的,但在windows底下。scripts中使用&&是有问题的。后来改了一下。直接把webpack -p这个指令当做生产环境。其他视为调试。

    获取到指令的第二个参数,为-p则判断为生产环境。
    var isProductEnv = process.argv[2] === '-p';
    

    然后可能需要不同环境配置一些变量。比如说HTTP请求的地址。因为这些都属于项目的内容。就不想在webpack.config.js中配置。直接配置到app文件夹中。在项目中判断当前环境,require对应的JSON数据。

    // webpack.config.js
    var DefinePlugin = require('webpack').DefinePlugin;
    var definePlugins = new DefinePlugin({
        webpack_prod : isProductEnv
    });
    module.exports = {
        ...
        plugins: [                                       
            definePlugins,
            ...
        ]
    }
    // index.js
    if (webpack_prod) {
        require('./env/product');
    } else {
        require('./env/test');
    }
    
    webpack-dev-server本地webserver

    启动:webpack-dev-server
    地址:http://localhost:port/webpack-dev-server/dist/index.html
    文档地址 :webpack-dev-server文档
    端口号默认是8080,可以在devServer中更改。每次改代码保存后,会自动编译并且刷新页面。还可以做到热替换即不刷新页面可以更新。除此之外还有一个proxy功能可以用来配置代理。

    压缩成项目名称_版本号.zip

    使用node.js的插件zip-local
    安装并加入项目中:
    npm install zip-local --save-dev
    项目目录下建立zip.js文件

    // 从package.json文件中获取到项目名称和版本号
    var packageInfo = require('./package.json');
    var zip = packageInfo.name + "_" + packageInfo.version;
    // 引入插件
    var zipper = require('zip-local');
    // 压缩dist文件夹
    zipper.sync.zip("dist/").compress().save(zip + ".zip");
    

    执行命令行 node zip 生成zip压缩文件。

    ▍第四步:开启nginx的gzip功能

    webpack打包编译后成一个文件,文件会比按需加载大。web项目在第一次加载的时候,文件太大的话会比较慢。所以要想办法把它的体积变小再变小。

    未压缩前,执行命令webpack

    ![](https://github.com/n98745/MarkdownPhotos/blob/master/webpack/3D5D26AE-AD6E-464E-8AB6-04490118096A.png?raw=true =100x100)

    先使用webpack自带的压缩,执行命令webpack -p

    ![](https://github.com/n98745/MarkdownPhotos/blob/master/webpack/20E389BE-0ABB-405D-8DD4-08B94D599BD1.png?raw=true =100x100)

    开启nginx的gzip功能

    官方文档:Module ngx_http_gzip_module
    翻译:Nginx官方文档翻译--ngx_http_gzip_module模块

    gzip on;
    gzip_proxied any;
    gzip_disable "msie6";
    gzip_comp_level 3;
    gzip_min_length 4k;
    gzip_types text/css text/xml application/javascript;
    
    开启后:

    ![](https://github.com/n98745/MarkdownPhotos/blob/master/webpack/5C448E36-480C-4071-8240-33BC35A48896.png?raw=true =100x100)
    这样子就把我们刚刚接近2M的项目代码压缩到150Kb。

    ▍webpack模块化

    webpack支持CommonJs和AMD规范。前者是同步加载,后者是异步加载。webpack加载的对象是module。它把静态资源都当做是模块。不仅仅只是js。还有css、html、图片等等都可以通过require去引入,如引入图片:

    var img = document.createElement("img");
    img.src = require("../image/xxx.jpg");
    document.body.appendChild(img);
    

    模块输出:module.exports = ...

    webpack resolve

    这个是在webpack.config.js中去配置的一个对象。它的几个用法:

    1. extensions
    // 当后缀名为空的时候,会自动识别并不缺
    resolve: { 
           extensions: ['', '.js'] 
    }  
    
    2. alias
    // 通过别名可以减少打包时间,项目中直接require("consts")重定向到指定的文件。
    resolve: { 
          alias: { 
              consts: path.resolve(__dirname, "app/util/constant.js")
          } 
    } 
    
    全局引入

    有时候像jquery想要给它配置全局,使用$去引入。
    首先安装依赖到项目中
    npm install --save-dev jquery
    配置plugins,然后就可以在项目中使用。

    plugins:[
        new webpack.ProvidePlugin({
            $:"jquery"
        })
    ]
    
    引入依赖

    项目中要用到angular,npm install --save-dev angular把依赖下载到文件夹node_modules中。
    通过require("angular")可以直接引入

    相关文章

      网友评论

          本文标题:webpack前端自动化构建方案

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