4-webpack5-基础、loader (02-02-02)

196 阅读3分钟

1. 现代Web开发“问题”

  • 采用模块化开发
  • 使用新特性提高效率保证安全性
  • 实时监听开发过程使用热更新
  • 项目结果打包压缩优化

2. Webpack 功能

  • 打包:将不同类型资源按模块处理进行打包
  • 静态:打包后最终产出静态资源
  • 模块: webpack 支持不同规范的模块化开发

3. ES Module 和 Commonjs 的区别

www.cnblogs.com/Happymoney/…

  1. 语法
    1. ES Module
      导出:export / export default
      导入: import * from 'module'
    2. Commonjs
      导出:module.exports
      导入:const module = require('module')

4. 打包命令、入口和出口配置

// 全局
webpack
// 局部
npx webpack
npm run build

webpack.config.js

const path = require('path')

module.exports = {
  // 入口文件
  entry: './src/index.js',
  // 输出文件
  output: {
    filename: 'build.js',
    path: path.resolve(__dirname, 'dist')
  }
}

5. webpack依赖图

  • 前端基于模块化的思想
  • 入口文件中如果想处理某个文件,必须引入进来
  • 自定义配置文件名称和入口文件

6. css-loader

  1. 为什么需要loader
    webpack只能处理js,没办法处理loader,进行资源转换和加载
  2. loader是什么
    加载和转换
  3. css-loader
    处理css语法,并不能展示样式
// 终端安装
npm i css-loader
// js
import '../css/login.css'

// package.json
"devDependencies": {
    "css-loader": "^6.2.0"
}

webpack.js 配置
三种写法

module: {
    rules: [
        {
           test: /\.css$/, 
           // 一般就是一个正则表达式,用于匹配我们需要处理的文件类型
           use: [
               {
                   loader: 'css-loader',
                    // 用户额外配置的参数
                    // options: 
               }
            ]  
        },
        {
           test: /\.css$/,
           loader: 'css-loader'
        },
        {
           test: /\.css$/,
           use: ['css-loader']
        }
    ]
}

7. style-loader

  1. 安装
npm i style-loader
  1. webpack.js
const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        // 从右往左,从下往上的执行顺序
        use: ['style-loader', 'css-loader']
      }
    ]
  }
}

8. less-loader

less -> css -> 展示

  1. 安装
npm i less
npm i less-loader
// 直接编译
npx less ./src/login.less index.css
  1. webpack.js
const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
      }
    ]
  }
}

9. browserslitrc工作流

获取兼容平台信息

  1. 工程化:
  2. 兼容性: CSS JS
  3. 如何实现兼容:
  4. 到底要兼容哪些平台
    caniuse.com 网站的Browser usage table统计了所有浏览器的占有规则。
>1% 占有率大于1
dead 长时间无更新 无维护
not dead 有人维护的
last 2 version:最后2个版本
maintained node versions #所有还被 node 基金会维护的 node 版本

webpack.config.js

"browserslist": [
    > 1% 
    last 2 version
    not dead
]

10. postcss工作流

  • postcss 是什么:
    利用javascript 转换样式的工具
  • less(less-loader) --> css --> css-loader
// 解析器
npm i postcss
// 兼容加前缀
npm i autoprefixer
// 可以在终端使用postcss
npm i postcss-cli
// 终端使用postcss -o 目标文件 源文件
npx postcss -o ret.css ./src/test.css

npx postcss --use autoprefixer -o ret.css ./src/test.css

.title {
  display: grid;
  transition: all 0.5s;
  user-select: none;
}

ret.css

.title {
  display: grid;
  -webkit-transition: all 0.5s;
  -o-transition: all 0.5s;
  -moz-transition: all 0.5s;
  transition: all 0.5s;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
}

11. postcss-loader 处理兼容

安装
npm i postcss-loader
npm i postcss-preset-env

webpack.config.js

const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      }
    ]
  }
}

postcss.config.js

module.exports = {
  plugins: [
    // rgba 透明度的兼容插件
    require('postcss-preset-env')
    // css处理后加前缀的插件
    require('autoprefixer')
  ]
}

12. importLoaders属性

原本的处理流程
postcss-loader -> @important -> css-loader -> style-loader

新的处理流程
postcss-loader -> @important -> css-loader -> postcss-loader -> style-loader

@import './test.css';
.title {
  color: #12345678;
}

webpack.config.js

  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              // 1是代表第一个处理postcss-loader
              importLoaders: 1
            }
          },
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      }
    ]
  }

13. file-loader

打包图片:

  • img src
    • 使用 require 导入图片,此时如果不配置 esModule: false ,则需.default 导出
    • 也可以在配置当中设置 esModule: false
    • 采用 import xxx from 图片资源,此时可以直接使用 xxxx
  • background url
.bgBox {
  width: 240px;
  height: 310px;
  border: 1px solid #000;
  background-image: url('../img/02.react.png');
}
import oImgSrc from '../img/01.wb.png'
import '../css/img.css'

function packImg() {
  // 01 创建一个容器元素
  const oEle = document.createElement('div')

  // 02 创建 img 标签,设置 src 属性
  const oImg = document.createElement('img')
  oImg.width = 600
  // oImg.src = require('../img/01.wb.png').default
  // oImg.src = require('../img/01.wb.png')
  oImg.src = oImgSrc
  oEle.appendChild(oImg)

  // 03 设置背景图片
  const oBgImg = document.createElement('div')
  oBgImg.className = 'bgBox'
  oEle.appendChild(oBgImg)

  return oEle
}

document.body.appendChild(packImg())

webpack.config.js

module: {
    rules: [
    {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              esModule: false
            }
          },
          'postcss-loader'
        ]
      },
      {
        test: /\.(png|svg|gif|jpe?g)$/,
        // use: [
        //   {
        //     loader: 'file-loader',
        //     options: {
        //       esModule: false // 不转为 esModule
        //     }
        //   }
        // ]
        use: ['file-loader']
      }
    ]
  }

14. 自定义图片打包产出

处理打包后的名字等属性

 * [ext]: 扩展名
 * [name]: 文件名
 * [hash]: 文件内容
 * [contentHash]:
 * [hash:<length>]
 * [path]:
module: {
    rules: [
      {
        test: /\.(png|svg|gif|jpe?g)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'img/[name].[hash:6].[ext]',
              // outputPath: 'img'
            }
          }
        ]
      }
    ]
  }

15. url-loader

  • 01 url-loader base64 uri 文件当中,减少请求次数,首次加载多
  • 02 file-loader 将资源拷贝至指定的目录,分开请求,首次加载少
  • 03 url-loader 内部其实也可以调用 file-loader
  • 04 limit属性
module: {
    rules: [
      {
        test: /\.(png|svg|gif|jpe?g)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              name: 'img/[name].[hash:6].[ext]',
              limit: 25 * 1024
            }
          }
        ]
      }
    ]
  }

15. asset模块类型

  • asset module type
  • 01 asset/resource -->file-loader( 输出路径 )
  • 02 asset/inline --->url-loader(所有 data uri)
  • 03 asset/source --->raw-loader
  • 04 asset (parser )
module: {
    rules: [
      {
        test: /\.(png|svg|gif|jpe?g)$/,
        type: 'asset/resource',
        generator: {
          filename: "img/[name].[hash:4][ext]"
        }
      },
      {
        test: /\.(png|svg|gif|jpe?g)$/,
        type: 'asset/inline'
      },
      // 合并
      {
        test: /\.(png|svg|gif|jpe?g)$/,
        type: 'asset',
        generator: {
          filename: "img/[name].[hash:4][ext]"
        },
        parser: {
          dataUrlCondition: {
            maxSize: 30 * 1024
          }
        }
      }
    ]
  }

16 asset打包图标字体

import '../font/iconfont.css'
import '../css/index.css'

function packFont() {
  const oEle = document.createElement('div')

  const oSpan = document.createElement('span')
  oSpan.className = 'iconfont icon-linggan lg-icon'
  oEle.appendChild(oSpan)

  return oEle
}

document.body.appendChild(packFont())

module: { rules: [ { test: /.(ttf|woff2?)$/, type: 'asset/resource', generator: { filename: 'font/[name].[hash:3][ext]' } } ] }