webpack 使用心得

来源:互联网 发布:折扇起源知乎 编辑:程序博客网 时间:2024/06/08 15:40

前言

最近项目中在使用react/redux/koa做一个IM,打包工具自然选择了webpack

我主要使用了webpack 的下列功能

  1. webpack 打包编译js文件

  2. 编译js文件支持多入口,版本控制,懒加载

  3. js和样式文件都支持热替换,不需要每个简单的修改都要刷新等待

  4. 复杂的css sprites功能,支持sass 语法

  5. 支持sourcemap,无论在开发还是上线的时候都支持soucemap的功能

webpack的功能不止这些了,而且社区比较活跃,插件开发也挺容易的,真心不错的一个工具

下面是具体功能实现部分

---------- 我是华丽的分割线 ----------

js 编译相关

webpack最基础的功能就是编译js了,由于react最近比较火热,而且react项目大部分都是通过webpack 进行打包编译的,导致很多人认为webpack 只是适用于react项目,这是不对的,webpack适用于所有的前端项目
我的项目也在使用react和sass

    entry: [        vendorCss: [            config.src.js + '/css/jquery.Jcrop.css'        ],        app: [            config.src.js + '/main.jsx'],        vendors:vendors]     },    output: {        path: config.dest.js,        filename: '[name].[chunkhash].js'    },    module: {        loaders:[{                test: /\.jsx?$/,                exclude: /node_modules/,                loaders: ['babel-loader'] //babel必须放在第一位,不然sourcemap是编译后的代码            }, {                test: /\.(png|jpg|gif)$/, loader: 'file-loader'            },{                test: /\.scss/,                loader: 'style!css!postcss!sass?sourceMap'            }, {                test: /\.css/,                loader: 'style!css'            }        ],        noParse: [            path.join(__dirname + '/client/node_modules/jquery/'),            path.join(__dirname + '/client/lib/**')        ]    }    

上面是一个简单的配置,页面的脚本分为两个vendor.js和app.js

上面的代码有一些潜在的坑:

  1. output.filename 中[name].[chunkhash] 中的chunkhash 并不只是内容变得时候才更新,默认的跟机器名,时间戳都有关系,如果要只是生成文件内容的md5,可以使用
    [webpack-md5-hash] ,也就是在plugins 里面添加 new WebpackMd5Hash()

  2. jsx的babel-loader必须放在第一位,如果需要jsx-loader,那么顺序就是
    ['babel-loader', 'jsx-loader'],否则生成的soucemap 代码是babel 编译后的es5 代码

  3. 关于懒加载,除了多入口的方式,也可以在项目中使用require.ensure的方式,点击此处查看更多

  4. 支持soucemap的话可以配置devtool 为'#cheap-module-eval-source-map',devtool有很多种,常见的sourcemap有下面几个问题

    1) sourcemap的代码是babel编译后的,这个主要是因为配置了devtool为eval,cheap-source-map2) sourcemap 中文乱码了,这个主要是配置了含有eval的devtool, 比如cheap-module-eval-source-map因此推荐开发的时候使用的sourcemap:cheap-module-source-map

    更多可以点此此处 ,

上线后代码会经过uglifyJsPlugin进行压缩,下面是相关配置

     new webpack.optimize.UglifyJsPlugin({        compress: {            warnings: false        },        sourceMap: true,//这里的soucemap 不能少,可以在线上生成soucemap文件,便于调试        mangle: true    })
  1. 上线后的devtool要配置为source-map,有时候为了性能考虑,一定要配置这个插件

    new webpack.DefinePlugin({

       'process.env': {       NODE_ENV: '"production"'   }

    })

  2. 可以在项目中配置一些alias,具体的可以查看此处,alias可以解决一些模块嵌套层级比较深,相对路径不好引用的bug

  3. 项目编译后生成的js 如果放到html页面里面呢?这里我自己写了一个插件,
    使用gulp-template 进行文件替换。

    export function  buildViewHtml(dev) {        return function () {            this.plugin("done", function (stats) {                stats = stats.toJson();                                let result = dev ? processDevHtml() : processProdHtml(stats.assetsByChunkName);//注意assetsByChunkName字段,包含chunkhash这些值                let sourceViewFile = path.join(__dirname, 'client', 'index.html');                let viewFile = path.join(__dirname, 'views');                gulp.src(sourceViewFile)                    .pipe(template({                        CSSHASH: result.cssHash ? JSON.stringify(result.cssHash) : null,                        appJS: result.app,                        vendorCss: result.vendorCss || null,                        vendorsJS: result.vendors                    }))                    .pipe(gulp.dest(viewFile));                });        }    }

使用的时候在plugins里面配置上buildHtml(false)

下面的内容是hrm相关的,今天先写到这里,后续会补充更多


热替换 Hot Module Replacement

热替换(Hot Module Replacement),简称HMR,
是说应用可以动态的更新局部模块代码,而不需要刷新整个页面

这个在跨平台开发或者较复杂的项目中特别有用,比如我有个层级很深的操作,操作了10多次才进入这个界面,这个时候更改了一个小功能,如果没有热替换,只能刷新整个页面,再重复操作10多次才能看到效果,热替换改变了这一切