likes
comments
collection
share

初涉Webpack

作者站长头像
站长
· 阅读数 53

Webpack记录文档

  1. 概念: webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
  2. 打包第一个文件:

    • 全局安装webpack:

      npm install webpack -g
    • 新建一个文件夹放入两个文件,一个为html一个为就是文件,其中HTML引入该js文件打包后的文件名
    • 执行webpack js文件 打包后的文件名
    • 此时如果出现报错:

      Cannot find module 'webpack-cli'
      请执行: npm install --save-dev webpack

      再执行出现:

      WARNING in configuration 
      The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
      请先执行 npm init -y, 生成package.json
      在新建一个webpack.config.js配置文件,用于配置webpack选项
      写入:
      const path = require('path')
      // 通过Node模块,向外面暴露一个配置
      module.exports = {
        entry:path.join(__dirname, './src/main.js'), // 打包文件
        output: {
          path: path.join(__dirname, './dist') // 打包好的文件名
        },
        mode: 'development' // 设置mode
      }

      此时再执行打包将无报错,且生成的文件将放入当前目录下的dist文件夹, 默认文件名为main.js

  3. 五大核心概念: | 中文名 | 配置项 | 概述 | | ---- | ---- | ---- | | 入口 | entry | 构建依赖图的开端 | | 输出 | output | 打包产出位置 | | 转化器 | loader | 编译的时候,对各种类型的模块, 进行转换处理 | | 插件 | plugin | 对每个任务环节,提供功能 | | 模式 | mode | 设置打包环境 |
  4. 认识webpack配置文件(即webpack.config.js)

    • 作用: 把配置参数,抽离到单独的文件,便于项目配置。
    • 基础格式:

      const path = require('path')    // node的基础path模块
      const 插件1 = require('插件1')
      module.exports = {
        //模式——设置开发模式
        mode: 'development',
        //入口——指定src/index.js为入口文件
        entry: {
          main: './src/index.js'
        },
        //输出——指定dist/bundle.js为输出文件
        output: {
          path: path.resolve(__dirname, 'dist'),
          filename: 'bundle.js'
        },
        //转换器。模块>规则
        module: {
          rules: [
            { test: /\.后缀名$/, 
              use: [
                {
                  loader: '转换器1',
                  options: {}    //转换器1配置
                }
              ]
            }
          ]
        },
        //插件
        plugins: [
          new 插件1({
            //插件配置
            })
        ]
      }
  5. 入口(entry):

    • 每个entry属性,对应一个入口文件,便于单页、多页应用的js引入,

      单页面入口
      entry: {
        main: './src/index.js
      }
      // 可缩写为entry: './src/index.js'
      多页面入口
       entry: {
         one: './src/one/index.js',
         two: './src/two/index.js',
         three: './src/three/index.js'
       }

    也可使用node的path模块实现获取相对于配置文件的路径

     const path = require('path')
     module.exports = {
       entry: path.resolve(__dirname, './app.js')
     }
     // 注意,这里的__dirname, 为两个下划线
    • entry支持三种格式:

      对象:

      entry: {
        <key>: <value>
      }
      // key可以是简单的字符串, 对应着output.filename配置中的[name]变量,
      entry: {
        'app-entry': './app.js'
      }
      // key还可以是路径字符串。此时webpack会自动生成路径目录,并将路径的最后作为[name]
      entry: {
        'path/of/entry': './app.js'
      }
      
      // value如果是字符串,而且必须是合理的noderequire函数参数字符串。比如文件路径:'./app.js'(require('./app.js'));比如安装的npm模块:'lodash'(require('lodash')) 
      
      entry: {
        'my-lodash': 'lodash'
      },
      output: {
        path: './output',
        filename: '[name].js'
      }

      数组:

      entry: ['./app.js', 'lodash']
      等价于:
      entry: {
        main: ['./app.js', 'lodash']
      }

      字符串:

      entry: './app.js'
      等价于
      entry: {
        main: './app.js'
      }
  6. output(输出)

    • output是影响编译输出的选项。output选项告诉webpack怎么把编译文件写入磁盘。注意,虽然可以有很多输入口,但是只有一个输出配置

      output: {
        path: path.resolve(__dirname, 'dist')
        filename: [name].js    // 使用[name]占位符,自动识别入口文件名,从而区分打包文件名
      }
    • output.filename: 指定输出到硬盘的文件的的文件名。这里不能是一个绝对的路径!output.path会确定该文件的存在硬盘额路径的。filename仅仅用来给每个文件命名而已。

      [name]被入口的名字替换.

      [hash]被编译器hash替换.

      [chunkhash] 被入口的hash替换.

    • output.path 编译后的文件存放路径,绝对路径,取[hash]将被编译后的文件hash替换
    • output.chunkFilename 非入口chunk的文件名,作为一个相对路径放到output.path里。
  7. module 配置如何处理模块

    • rules配置模块的读取和解析规则,通常用来配置Loader,类型是一个数组,数组里的每一项都描述了怎么去处理特定的文件。

    匹配规则:

    1. 条件匹配: 通过test/include/exclude三个配置项来命中Loader要应用的规则文件
    2. 应用规则: 对选中的文件通过use配置项来应用loader,可以应用一个loader或者从后往前应用一组loader,同时还可以分别给loader传入参数。
    3. 重置顺序,一组loader的执行顺序默认是从右到左执行,通过exforce选项可以让其中一个loader的执行顺序放到最前或者最后。
    
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['babel-loader?cacheDirectory'],
                include: path.resolve(__dirname, 'src')
            },
            {
                test: /\.scss$/,
                use: ['style-loader', 'css-loader', 'sass-loader'],
                exclude: path.resolve(__dirname, 'node_modules')
            },
            { // test、include、exclude还支持数组类型
                test: [/\.jsx?$/, /\.tsx?$/],
                include: [
                    path.resolve(__dirname, 'src'),
                    path.resolve(__dirname, 'test')
                ],
                exclude: [
                    path.resolve(__dirname, 'node_modules'),
                    path.resolve(__dirname, 'bower_modules')
                ]
            }
        ]
    }
    
    • 在loader需要传入很多参数的时候,我们还可以通过一个object来描述,如:

      use: [
          {
              loader: 'babel-loader',
              options: {
                  cacheDirectory: true
              },
               // enforce:'post' 的含义是把该 Loader 的执行顺序放到最后
              // enforce 的值还可以是 pre,代表把 Loader 的执行顺序放到最前面
              enforce:'post'
          }
      ]
    • noParse: 可以让webpack忽略部分未采用模块化的文件的递归解析和处理,类型可以为RegExp, [RegExp], function其中一个
    • 常见的loader配置:

      { // 加载图像
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          'file-loader'
        ]
      }
      
      { // 加载字体
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
          'file-loader'
        ]
      }
      
      { // 加载css
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      }
      
  8. plugins:

    //通过new实例,启用插件
    plugins: [
      new webpack.ProgressPlugin(),    //webpack自带一系列插件
      new HtmlWebpackPlugin({template: './src/index.html'})    //使用对象,为插件配置参数
    ]

    常见的plugin:

    • HotModuleReplacementPlugin –开启全局的模块热替换(HMR);
    • NamedModulesPlugin –当模块热替换(HMR)时在浏览器控制台输出对用户更友好的模块名字信息;
    • CommonsChunkPlugin –提取chunk公共部分;
    • ExtractTextPlugin –独立生成css文件,以外链的形式加载;
    • UglifyJsPlugin –压缩js;
    • HtmlWebpackPlugin –使用模版生成html。
  9. 环境变量:

    webpack可以设置环境变量以区分生产模式还是开发模式,由此执行不同的操作。

    const NODE_ENV = process.env.NODE_ENV // 可获取到环境变量
    可由此对目前是生产模式还是开发模式
  10. 开发模式:webpack.dev.js配置文件
  11. 生产模式:webpack.prod.js配置文件
  12. resolve: webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀。例如:

    resolve: {
        nodules: [path.resolve(__dirname, "node_modules")],
        extensions: ['.js', '.json', '.scss', '.vue', '.json']
        // 模块别名定义,方便后直接引用别名, 无需多写长地址
        alias: {
          '@/static': resolve('static'), // 将@/static指向当前项目,下的static目录
          '@': resolve('src'), // 将@指向src目录
        }
    }
  13. 命令:

    //开发模式,启动服务器
    webpack-dev-server --open --config webpack.dev.js
    //生产模式,打包
    webpack --config webpack.prod.js
  14. webpack还可以支持Node操作,可通过Node对现有文件进行操作,以满足打包所需。

使用demo参考: 阮一峰的https://github.com/ruanyf/web...