欢迎来到吴小小的专栏!

webpack学习笔记

https://webpack.js.org

1 entry: string|Array

module.exports = {
  entry: './path/to/my/entry/file.js'   //entry:['./a.js','./b.js']如果是个数组,会按顺序打包到一个文件里面
};

module.exports = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js' //多个入口文件对应多个output输出文件
  }
};

2 output

const path = require('path');

module.exports = {
  output: {
    path:path.resolve(__dirname, 'dist'),//打包后的文件存放的地方
    filename: "bundle.js",//打包后输出文件的文件名
  },
publicPath:'http:ifchange.com' //css或者html用到相对路径时,在生产环境,会使用cdn前缀,加上publicPath不会有这个问题
}

module.exports = {
  output: {
    filename: '[name].[hash:7].js', //如果配置创建了多个单独的 "chunk",则应该使用占位符(substitutions)来确保每个文件具有唯一的名称。
                                                    //取7位hash值;文件更新之后生成不一样的hash值,防止缓存
    path: __dirname + '/dist'
  }
}

3 loader

loader 让 webpack 能够去处理那些非 JavaScript 文件

  1. 识别出应该被对应的 loader 进行转换的那些文件。(使用 test 属性)
  2. 转换这些文件,从而使其能够被添加到依赖图中(并且最终添加到 bundle 中)(use 属性)

在你的应用程序中,有三种使用 loader 的方式:

  • 配置(推荐):在 webpack.config.js 文件中指定 loader。
  • 内联:在每个 import 语句中显式指定 loader。
  • CLI:在 shell 命令中指定它们。
//配置
module.exports = {
...
  module: {
    rules: [
      {
        test: /\.css$/,  //里面包含两个必须属性:test 和 use
        use: [ //数组
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }
}

//内联 使用 ! 将资源中的 loader 分开。分开的每个部分都相对于当前目录解析。
import Styles from 'style-loader!css-loader?modules!./styles.css'

//include 匹配以下路径文件
//exclude 排除以下路径文件
//options loader的配置参数
//oneof  数组,当规则匹配时,只使用第一个匹配规则。
//parser
parser: {
  amd: false, // 禁用 AMD
  commonjs: false, // 禁用 CommonJS
  system: false, // 禁用 SystemJS
  harmony: false, // 禁用 ES2015 Harmony import/export
  requireInclude: false, // 禁用 require.include
  requireEnsure: false, // 禁用 require.ensure
  requireContext: false, // 禁用 require.context
  browserify: false, // 禁用特殊处理的 browserify bundle
  requireJs: false, // 禁用 requirejs.*
  node: false, // 禁用 __dirname, __filename, module, require.extensions, require.main 等。
  node: {...} // 在模块级别(module level)上重新配置 node 层(layer)
}

4 plugin

插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

webpack 插件是一个具有 apply 属性的 JavaScript 对象。apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
const path = require('path');
...
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var DashboardPlugin = require('webpack-dashboard/plugin');

module.exports = {
  module: {
    plugins: [
      // build optimization plugins
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: 'vendor-[hash].min.js',
      }),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false,
          drop_console: false,
        }
      }),
      new ExtractTextPlugin({
        filename: 'build.min.css',
        allChunks: true,
      }),
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      // compile time plugins
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"', //设置全局环境变量
      }),
      // webpack-dev-server enhancement plugins
      new DashboardPlugin(),
      new webpack.HotModuleReplacementPlugin(),
    ]
  }
}

5 模块解析

import "module/lib/file";

如果路径指向一个文件:

  • 如果路径具有文件扩展名,则被直接将文件打包。
  • 否则,将使用 [resolve.extensions] 选项作为文件扩展名来解析,此选项告诉解析器在解析中能够接受哪些扩展名(例如 .js, .jsx)。

如果路径指向一个文件夹

  • package.json 文件中的 main 字段返回一个有效路径,在文件夹下找到这个文件
  • 如果 package.json 文件不存在或者 package.json 文件中的 main 字段没有返回一个有效路径,则按照顺序查找 resolve.mainFiles 配置选项中指定的文件名,看是否能在 import/require 目录下匹配到一个存在的文件名。
  • 文件扩展名通过 resolve.extensions 选项采用类似的方法进行解析。

6 resolve

module.exports = {
    resolve: {
        extensions: [".js", ".json", ".jsx", ".css"],//resolve一些在import文件时不带文件扩展名的表达式
        alias: {
            'tob': path.join(__dirname, './app/static/tob/'), //对路径起别名
        },
    }
}

7 devServer

module.exports = {
        port: 9001,
        contentBase: './dist',
        public: 'http://localhost:9001',
        compress:true,//为所有服务启用gzip压缩,在response header里Content-Encoding:gzip
        before(app) { //提供在服务器内部的所有其他中间件之前执行定制中间件的功能,当其他服务器获取dist目录下面的资源,设置允许所有域名获取
            app.use(function (req, res, next) {
                res.set('Access-Control-Allow-Origin', '*');
                next();
            });
        }
}

8 devtool

有很多种模式,

module.exports = {
    devtool: 'source-map',
}

source-map

//# sourceMappingURL=index.js.map 在bundle文件尾部生成一个注释
与此同时,你会发现你的 output 目录下多了一个 index.js.map ,这里面有bundle文件的行,列,,,信息

  1. 使用 cheap 模式可以大幅提高 souremap 生成的效率。大部分情况我们调试并不关心列信息,而且就算 sourcemap 没有列,有些浏览器引擎(例如 v8) 也会给出列信息。
  2. 使用 eval 方式可大幅提高持续构建效率。官方文档提供的速度对比表格可以看到 eval 模式的编译速度很快。
  3. 使用 module 可支持 babel 这种预编译工具(在 webpack 里做为 loader 使用)。
  4. 使用 eval-source-map 模式可以减少网络请求。这种模式开启 DataUrl 本身包含完整 sourcemap 信息,并不需要像 sourceURL 那样,浏览器需要发送一个完整请求去获取 sourcemap 文件,这会略微提高点效率。而生产环境中则不宜用 eval,这样会让文件变得极大。

9 常用plugin

const HtmlWebpackPlugin = require('html-webpack-plugin'); //生成html模板
new HtmlWebpackPlugin({
inject: true,//生成的script标签在body底部
filename: path.join(__dirname, 'app/view/index.html'),//指定文件名,可以获取HtmlWebpackPlugin的配置options
template: path.join(__dirname, 'app/static/index.html'),//指定模板 由模板生成文件
}),

const ExtractTextPlugin = require("extract-text-webpack-plugin");
new ExtractTextPlugin("css/[name].[contenthash:8].css") //将所有style提取到css文件夹中生成对应的文件

const CleanWebpackPlugin = require('clean-webpack-plugin');//清楚指定路径插件缓存
new CleanWebpackPlugin(distPath)

const webpack = require('webpack');
new webpack.optimize.CommonsChunkPlugin({
name: "commons",//entry里面的块名
filename: "js/commons.[hash:8].js"//将公共块生成一个文件,提高性能
}),
new webpack.DefinePlugin({ //定义全局变量,
"process.env.NODE_ENV": JSON.stringify(ENV)//JSON.stringify变为字符串
}),
new webpack.HotModuleReplacementPlugin() //热模块替换,
HMRnew webpack.optimize.UglifyJsPlugin({ //使用 UglifyJS 去压缩你的JavaScript代码
sourceMap: true,
beautify: false,
comments: false,
compress: {
warnings: false,
collapse_vars: true,
reduce_vars: true
}
}),

cross-env

cross-env这使得你可以有一个单一的命令,而不必担心为平台设置或使用环境变量。只要像在POSIX系统上运行一样cross-env进行设置,就可以正确设置。

npm install --save-dev cross-env

{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
  }
}

webpack --progress --colors //显示进度,改变颜色

posted @ 2020-01-17 15:57  吴小小  Views(219)  Comments(0Edit  收藏  举报