唯雪博客

webpack爬坑记录(二)

对于配置过程本文就不一一赘述了,只是简单就一些配置可能遇到的问题做个总结

唯雪博客

先看webpack.config.js基本配置

入口和出口

entry:{
       index:__dirname + "/src/main.js",//唯一入口
   },
output:{
   path:path.resolve(__dirname+"/dist"),
   filename:"[name]-[hash].js"
},

入口和出口,单页应用唯一的入口文件,这个没什么好说的

需要注意的是如果用的是2x以上版本的webpack,如果output的filename直接写bundle.js压缩防止重复时会报错

唯雪博客

接下来是常用的loader

module: {//loader定义的地方,使用前需要npm 安装
      rules: [
          {
              test:/(\.html)$/,
              use:{
                  loader:"html-loader",
              },
          },{//处理es6语法,和jsx语法
              test:/(\.jsx|\.js)$/,
             use:{
               loader:"babel-loader",
             },
             exclude:/node_modules/
           },{
              test: /\.(png|gif|jpe?g)$/,
              loader: 'url-loader',
              query: {
                  /*
                   *  limit=10000 : 10kb
                   *  图片大小小于10kb 采用内联的形式,否则输出图片
                   * */
                  limit: 10000,
                  name: '/img/[name]-[hash:8].[ext]'
              }
          },{
              test: /\.css$/,
              use: extractCSS.extract({
                  fallback:"style-loader",
                  use:[ 'css-loader']
              })
          },
          {
              test: /\.less$/i,
              use: extractLESS.extract({
                  fallback:"style-loader",
                  use:[ 'css-loader', 'less-loader']
              })
          },
        ]
  }

配置module需要注意一下几点:

一、file-loader和url-loader

url-loader封装了file-loader。url-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。通过上面的介绍,我们可以看到,url-loader工作分两种情况:1.文件大小小于limit参数,url-loader将会把文件转为DataURL;2.文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。因此我们只需要安装url-loader即可。

二、处理es6,es7语法 babel

        除了安装babel-core babel-loader 还要安装转码es对应的babel-preset-esXX。

        之前看到很多博客提到babel-preset-env处理一切版本的es不需要再麻烦的去安装每个版本。尝试了几次,开发没有问题,es6,es7的语法都可以正常解析为es5。但是再压缩js的时候始终报错。

        唯雪博客

表面上看是报的静态资源的问题,通过断点测试,其实是es6语法不支持,于是我安装了babel-preset-es2015,配置了.babelrc文件

//.babelrc
{
  "presets": ["react", "es2015"]
}

问题得到了解决

唯雪博客

代码从1.9M压缩到了几百K

三、抽离从js中抽离css,html等静态资源

上述代码中的extractCESS,extractLESS是extract-text-webpack-plugin插件实例化的对象

使用时首先要npm install 安装改插件。使用时除了再module中配置意外还需要再plugin中声明

//webpack.config.js
plugins:[
    extractCSS,
   extractLESS
]

常用的插件plugin

plugins:[
        /*
         *create html file
         * (创建html文件)
         * */
	new HtmlWebpackPlugin({
		template:__dirname+"/src/index.tmpl.html"
	}),
        new HtmlWebpackPlugin({
            filename: 'html/tmpl.html',
            template: __dirname + '/src/tmpl.html',
            inject: false,
        }),
        /*
         *  Module (value) is loaded when the identifier (key) is used as free variable in a module
         *  (如:使用jquery 可以直接使用符号 "$")
         * */
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery",
            "_": "underscore"
        }),
        /*
        *热加载插件,如果配合react使用,
        *需要安装babel-plugin-react-transform react-transform-hmr配合babel
        * */
        new webpack.HotModuleReplacementPlugin(),
        /*
        *清除打包文件夹中多余的js文件
        * */
        new cleanWebpackPlugin(['dist']),
        extractCSS,
        extractLESS,
        /*
        * CommonsChunkPlugin(防止重复)
        * */
        new webpack.optimize.CommonsChunkPlugin({
            name:'common'//指定公共的bundle的名称
        })
],

都是一些常用的插件没有太多需要解释的,不过上面配置ProvidePlugin时,直接使用“jquery”是因为我再resolve中对资源进行了重命名

解析resolve

resolve: {
   /*
   * An array of extensions that should be used to resolve modules
   * (引用时可以忽略后缀)
   * */
  extensions: ['.js', '.css', '.scss','.less','.ejs', '.png', '.jpg','.html'],
  alias: {
     /*
     * js
     */
     jquery: path.join(path.resolve(process.cwd(), './libs'), "js/jquery"),
     /*
     * css,bootstrapcss重命名,需要引用的地方,可以直接require别名无需写路径,非常方便
     */
     bootstrapcss: path.join(path.resolve(process.cwd(), './libs'), "bootstrap/bootstrap-3.3.5.css"),
  }
}

简单说明一下:path.resolve和process.cwd()都是nodejs的方法

path.resolve() 方法会把一个路径或路径片段的序列解析为一个绝对路径。

给定的路径的序列是从右往左被处理的,后面每个 path 被依次解析,直到构造完成一个绝对路径。 例如,给定的路径片段的序列为:/foo/barbaz,则调用 path.resolve('/foo', '/bar', 'baz') 会返回 /bar/baz

process cwd() 方法返回 Node.js 进程当前工作的目录。

所以path.resolve(process.cwd(), './libs')翻译成人话就是:当前项目下的libs文件夹下

最后说明一下环境的构建:

开发模式下配置一个可以热更新和自动打开浏览的服务器

//webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.config.js');

module.exports = merge(common, {
    devtool: 'inline-source-map',
    devServer: {
        contentBase:"./dist",//本地服务器所加载的页面所在的目录
        historyApiFallback:true,//不跳转
        inline:true,//实时刷新
        hot:true,//热加载
        open:true//自动打开浏览器
    }
});

生产模式下需要压缩代码

//webpack.prod.js

const webpack = require("webpack")
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.config.js');
module.exports = merge(common, {
     devtool:"source-map",
      plugins: [
         new UglifyJSPlugin({
            sourceMap:true
         }),
          new webpack.DefinePlugin({
          /*
          *许多 library 将通过与 process.env.NODE_ENV 环境变量关联,以决定 library 中应该引用哪些内容。
          */
              "process.env":{
                  'NODE_ENV':JSON.stringify('production')
              }
          })
      ]
 });

ps:技术上讲,NODE_ENV 是一个由 Node.js 暴露给执行脚本的系统环境变量。通常用于决定在开发环境与生产环境(dev-vs-prod)下,服务器工具、构建脚本和客户端 library 的行为。然而,与预期不同的是,无法在构建脚本 webpack.config.js 中,将 process.env.NODE_ENV 设置为 "production",请查看 #2537。因此,例如 process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js' 这样的条件语句,在 webpack 配置文件中,无法按照预期运行。

//package.json
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "start": "webpack",
  "dev": "webpack-dev-server --open --config webpack.dev.js",
  "build": "webpack --config webpack.prod.js"
},

在node命令行中运行npm run dev 就会开启开发模式

运行,npm run build 项目会被打包到dist目录下,上线时只需要上传dist目录下的文件即可

总结,这个配置在性能优化方面可能还是不足,不过,基本已经实现了打包,分离开发模式与生产模式。源码也都穿上来了,与兴趣的可以下载参考。

webpack-study-2018.zip




白俊遥博客
请先登录后发表评论
  • 最新评论
  • 总共1条评论
白俊遥博客

越过死海白俊遥博客

2018-01-11 10:12:29 回复