webpack基础部分

webpack静态资源打包器

1 webpack五个核心概念

1.1 Entry

入口,指示webpack以哪个文件为起点开始打包,分析构建内部依赖图

1.string --> ‘./src/index.js’

单入口,宝宝形成一个chunk,输出一个bundle文件,chunk名称默认为mian

2.array --> [’./src/index.js’, ‘./src/index.html’]

多入口,多有入口文件最终只会形成一个chunk,输出出去也只有一个bundle文件

    entry: ['./src/index.js', './src/index.html'],

主要作用: 只有在hmr功能中html热更新生效

3.object -->

entry: {
    index: './src/index.js',
    add: './src/add.js'
}

多入口,有几个入口就有几个文件,chunk名字为key

–> 特殊用法

entry: {
    //多文件一个chunk
    index: ['./src/index.js', './src/index.html'],
    //一个文件
    add: './src/add.js'
}

1.2 Output

输出指示 webpack 打包后的资源bundlies输出到哪去,以及如何命名

  output: {
    filename: 'js/built.[chunkhash:10].js',
    
    // 输出路径  __dirname是 Nodejs的变量  代表当前文件是目录的绝对路径
    (所有资源输出的公共目录)
    path: resolve(__dirname, 'build'),
    
    //所有输出资源引入的公共路径前缀 --> 'imgs/a.jpg'-->'/imgs/a.jpg'
    publicPath:'/',
    
    //非入口chunk名称
    //如import()动态引入方式
    chunkFilename: 'js/[name]_chunk.js',
    
    //整个库向外暴露的变量名
    library:'[name]',
    //添加到浏览器window,添加到node上,global;commonjs
    libraryTarget: 'window'
  },

1.3 Loader

让其能够处理那些非js文件(webpack自身职能理解js)

module: {
    rules: [
    {
        test:/\.css$/,
        //多loader
        use:['style-loader','css-loader']
    },
    {
        test: /\.js$/,
        //排除node_modules下的js文件
        exclue:/node_modules/,
        //只检查src下的js文件
        include: resolve(__dirname,'src'),
        //优先执行pre    延后执行post
        enforce:'pre',
        //单loader
        loader:'eslint-loader',
        options:{}
    },
    {
    //以下配置只会生效一个
        oneOf:[]
    }
    ]
}

常用详细配置

module: {
    rules: [
      // 正常来说 一个文件只能被一个loader处理
      // 当要被多个Loader处理的时候 需要弄清执行的顺序  比如 先要 执行 eslint 在执行babel转换  ,不然 先babel转换成es5的话,再eslint回报错
      // 使用enforce:'pre'属性

      /**
       * 语法检查 eslint-loader eslint
       * 注意 只检查源代码,第三方不查
       * 设置检查规则:
       * package.json中eslintConfig设置
         "eslintConfig": {
            "extends": "airbnb-base"
          }
       * airbnb语法检查规则需要 eslint eslint-loader eslint-config-airbnb-base eslint-plugin-import
       */
      {
        test: /\.js$/,
        exclude: /'node_modules'/,
        enforce: 'pre', // 优先执行
        loader: 'eslint-loader',
        options: {
          // 自动修复
          fix: true,
        },
      },
      {
        // 以下loader只会匹配一个 优化生产环境构建速度
        //  不能有两个配置处理一中类型的文件
        // 不用oneOf的话 每个文件都要被所有Loader过滤一遍
        oneOf: [
          {
            // test匹配那些文件  .css结尾
            test: /\.css$/,
            // use 使用那些loader进行处理
            use: [
              // 执行顺序,从右到左,从下到上依次执行
              // 创建style标签, 将js中的样式资源插入进行,添加到head中生效
              // 'style-loader', //  开发模式用 能热更
              // 这个loader取代style-loader,作用提取js中的css为单独文件(所以就不需要创建style标签)
              MiniCssExtractPlugin.loader,
              // 将css文件变成commonjs模块 加载js中 里面内容是样式字符串
              'css-loader',
              /**
                 * css兼容性处理 : postcss ==> postcss-loader postcss-preset-env(识别环境)
                 */
              {
                loader: 'postcss-loader',
                options: {
                  idnet: 'postcss',
                  plugins: () => [
                    // postcss插件
                    // 帮助postcss找到package.josn中browserslist里面的配置,通过配置加载指定的css兼容样式
                    // "browserslist": {
                    //   "develoment": [   //使用这个的话 需要// 设置node环境变量process.env.NODE_ENV = 'develoment';
                    //     "last 1 chrome version",
                    //     "last 1 firefox version",
                    //     "last 1 safari version"
                    //   ],
                    //   "production":[   //默认使用生成的
                    //     ">0.2%",   兼容99.8的浏览器
                    //     "not dead",  不要已经挂掉的流量器
                    //     "not op_mini all"  不兼容op_mini
                    //   ]
                    // }
                    require('postcss-preset-env')(),
                  ],
                },
              },
            ],
          },
          // 不同文件需要不同的loader处理
          {
            test: /\.less$/,
            // use 放数组是使用多个loader处理例子

            use: [
              // 创建style标签
              // 'style-loader',
              // 这个loader取代style-loader,作用提取js中的css为单独文件(所以就不需要创建style标签)
              ...commonCssloader,
              // 将less文件编译成css文件 需要下载less和less-loader
              'less-loader',
            ],
          },

          // 处理图片资源
          // 默认处理不了 html img中图片
          {
            test: /\.(jpg|png|gif)$/,
            // 只使用一个的话 直接loader
            // 需要url-loader 和其依赖 file-loader
            loader: 'url-loader',
            options: {
              // 当发现图片大小小于8kb就会被base64处理,
              // 优点: 减少请求数量 缺点: 图片体积会变大
              limit: 8 * 1024,
              // 因为 url-loader默认ex6解析  html-loader是commonjs 所以解析会报错  
              // 解决  关闭url-loader的es6模块化解析
              esModule: false,
              // 给图片进行重命名
              // [hash:10]取图片哈希值前10位
              // [ext]取原来拓展名
              name: '[hash:10].[ext]',
              outputPath: 'imgs',
            },
          },
          {
            test: /\.html$/,
            // 处理html中img图片 负责引入img,从而能被urlloader处理
            loader: 'html-loader',
          },

          // 打包其他资源
          {
            exclude: /\.(css|js|html|less|jpg|png|gif)$/,
            loader: 'file-loader',
            options: {
              outputPath: 'font',
            },
          },

          /**
       * js兼容性处理  babel-loader @babel/preset-env @babel/core
       * 1. 基本的js兼容性处理  @babel/preset-env  问题 只能转换基本语法  promise等 不能转换
       * 2.全部兼容性处理 ==> @babel/polyfill
       * import '@babel/polyfill'  全部引入 增大代码体积
       * 3.需要做兼容的才做  按需加载
       * core-js
       *
       * 2和3不能同时用    直接结合用 1  -  3
       */
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
              // 预设  指示babel做怎么样的兼容性处理
              presets: [
                ['@babel/preset-env',
                  {
                    useBuiltIns: 'usage', // 按需加载
                    corejs: { version: 3 }, // 制定corejs的版本
                    targets: { // 指定具体的兼容性的版本
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17',
                    },
                  },
                ],
              ],
              // 开启babel缓存
              // 第二次构建时 会读取之前的缓存
              // 需要给 输出文件带上hash值  不然无法更新变化
              cacheDirectory: true,
            },
          },
        ],
      },
    ],
  },

1.4plugins

插件 让其执行更广的任务,如压缩,优化,重新定义环境变量等

常用插件

// resolve 用来专门拼接绝对路径的方法
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 提取css为单独的文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// optimize-css-assets-webpack-plugin  压缩css插件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// 允许您将现代CSS转换为大多数浏览器都能理解的内容,根据目标浏览器或运行时环境确定所需的polyfill。
const PostcssPresetEnv = require('postcss-preset-env');

// 设置node环境变量
process.env.NODE_ENV = 'develoment';
plugins: [
    // html-webpack-plugin
    // 功能 默认创建一个空的 html 自动移入打包输出的所有资源(js,css)

    new HtmlWebpackPlugin({
      template: './src/index.html',
      // 压缩html配置
      minify: {
        collapseWhitespace: true, // 折叠空格
        removeComments: true, // 移除注释
      },
    }),

    new MiniCssExtractPlugin({
      filename: 'css/index.[chunkhash:10].css',
    }),

    new OptimizeCssAssetsWebpackPlugin(),
  ],

1.5Mode

指示webpack使用相应模式的配置

  mode: 'development',
  // mode: 'production'    生成环境会自动压缩js

1.6 devServer

  devServer: {
    //运行代码的目录
    contentBase: resolve(__dirname, 'build'),
    //监视contentBase目录下的所有文件 一旦有变化 就会重载
    watchContentbase: true,
    // 启动gzip压缩,服务器起的就快
    compress: true,
    // 端口号
    port: 3000,
    //域名
    host:'localhost',
    // 打开默认浏览器
    open: true,

    /**
     * 开启HMR功能
     *  HMR: hot module replacement / 热模板替换
     * 作用: 一个模板发生变化,只会重新打包这一个模块(默认是打包所有)
     * 当修改配置,必须重启webpack
     *
     * 样式文件: 可以使用hmr功能,因为style-loader内部里面实现了这个功能
     * js文件:  默认不能使用hmr功能  需要修改js代码 添加支持hmr功能的代码
     *   注  :   只能处理非入口的js文件  使用module.hot.accept()进行监听
     * html文件:  默认不能  解决: 修改 entry 入口,将html引入
     *
     */
    hot: true,
  },

1.7 source-map

devtool: 'eval-source-map',
/**
   * source-map
   * 一种提供源代码到构建后代码映射技术 (如果 构建后代码出错了 可以通过映射追踪源代码错误)
   * 内联和外联区别: 1.外部生成了文件,内联没有   2. 内联构建速度快
   *
   * inline-   内联
   *  只生成一个内联source-map 提示错误代码的准确信息和 源代码位置
   * eval-  内联
   *  每个文件都生成一个source-map 都在eval函数里  提示错误代码的准确信息和 源代码位置
   *
   * source-map  外联
   *  提示错误代码的准确信息和 源代码位置
   * hidden-  外联
   *  提示错误代码原因 但是没有位置,只能提示到构建后的错误位置,隐藏源代码
   * nosources- 外联
   * 提示错误代码错误信息 但是没有位置,隐藏源代码
   * cheap- 外联
   * 提示错误代码的准确信息和 源代码位置
   * 但是错误信息 只精确到行
   * cheap-module- 外联
   * 提示错误代码的准确信息和 源代码位置
   * module会将loader的source map 加入
   *
   *
   * 开发环境:速度快  调试友好
   * 速度(eval>inline>cheap)
   * eval-cheap-source-map>eval-source-map
   * 调试
   * source-map>cheap-module-source-map>cheap-source-map
   *
   * 综合选择 ::: eval-source-map
   *
   *
   * 生产环境: 源代码是否隐藏? 调试要不要更友好
   *
   * 内联会让代码体积变很大
   * nosources-source-map 全部隐藏
   * hidden-source-map 只隐藏源代码 会提示构建后代码错误信息
   *
   *  综合选择 ::: source-map
   */

1.8 resolve解析模块规则

    resolve: {
    // 配置解析模块路径别名
        alias:{
            @:resolve(__dirname,'src/css')
        },
    // 配置省略路径后缀名的规则  默认值 js,json,会顺序查找
        extensions:['.js','.json','.jsx'],
    //告诉webpack解析模块默认找那个目录
    //则引入src下的utils模块,就可以
    //import 'utils'
        modules: [resolve(__dirname,'../../src')]
    }

2 运行

2.1 运行指令

开发环境 webpack ./src/index.js -o ./build/build.js --mode=development

-o: 输出位置

生产环境 webpack ./src/index.js -o ./build/build.js --mode=production

结论

  1. webpack能处理js/json资源 不能处理img/css等其他资源
  2. 生产环境和开发环境将es6模块化编译器浏览器能识别的模块化
  3. 生产环境比开发环境 多一个js压缩代码

你可能感兴趣的:(知识)