webpack5-Loader

小江不可求

webpack5(Loader)

一、webpack发展

现代Web开发"问题":

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

使用webpack实现项目项目工程化

1.Webpack功能

打包:将不同类型的资源按模块的处理进行打包
静态:打包后最终产出静态资源
模块:webpack支持不同规范的模块化开发(兼容多种模块导入形式)

安装webpack:

yarn add -D webpack webpack-cli

2.Webpack配置文件

在项目根目录下,新建webpack.config.js配置文件,使用webpack命令打包时,会自动使用该配置文件打包项目

const path = require('path')

module.exports = {
   entry:'./src/main.js',
   output:{
        path:path.resolve(__dirname,'dist'), // 这里必须要配置为绝对路径
        filename:'bundle.js',
        environment: {
            arrowFunction: false    // 打包时不使用箭头函数包裹,在ie中运行时,注意
        }
   }
}

output.environment
告诉 webpack 在生成的运行时代码中可以使用哪个版本的 ES 特性。

module.exports = {
  output: {
    environment: {
      // The environment supports arrow functions ('() => { ... }').
      arrowFunction: true,
      // The environment supports BigInt as literal (123n).
      bigIntLiteral: false,
      // The environment supports const and let for variable declarations.
      const: true,
      // The environment supports destructuring ('{ a, b } = obj').
      destructuring: true,
      // The environment supports an async import() function to import EcmaScript modules.
      dynamicImport: false,
      // The environment supports 'for of' iteration ('for (const x of array) { ... }').
      forOf: true,
      // The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
      module: false,
    },
  },
};

作者:ppzhang
链接:https://juejin.cn/post/6970155119643983879
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

指定配置文件打包:

webpack --config lg.webpack.js

二、Loader使用

1.cssLoader的使用

未使用css-loader之前的代码:

import '../css/login.css';

function login() {
    const oH2 = document.createElement('h2');
    oH2.innerHTML = '江江学前端';
    oH2.className = 'title';
    return oH2;
}
document.body.appendChild(login());

css-loader 可以将文件从不同的语言 css 转换为 JavaScript
安装css-loader:

yarn -D add css-loader

使用css-loader
行内使用:

import 'css-loader!../css/login.css'; 
// css-loader只将css处理成当前js可以识别或处理的模块类型,不会将css文件导入进index.html中
// style-loader将css插入到head中

配置到配置文件中使用:

const path = require('path')

module.exports = {
   entry: './src/main.js',
   output: {
      path: path.resolve(__dirname, 'dist'), // 这里必须要配置为绝对路径
      filename: 'bundle.js'
   },
   module: {
      rules: [
         // {
         //    test: /\.css$/, // 一般就是一个正则表达式,用来匹配文件类型
         //    use: [
         //       {
         //          loader: 'css-loader'
         //       }
         //    ]
         // }

         // 简写  只使用一个loader处理
         {
            test: /\.css$/,
            loader: 'css-loader'
         }

         // 简写 是、使用多个loader处理,但一般不使用参数
         // {
         //    test: /\.css$/,
         //    use:[
         //       'css-loader',
         //    ]
         // }
      ]
   }
}

2.style-loader使用

style-loader的作用:
在head标签中插入一个style标签,并填入处理好的css样式
下载:

yarn -D add style-loader

配置loder:

rules: [
         {
            test: /\.css$/,
            use: ['style-loader', 'css-loader'] // loaders的执行顺序是从右到左
         }
      ]

3.less-loader使用

less-loader的作用:

内部调用less,将less代码编译成css代码

安装:

yarn -D add less less-loader

配饰loader:

  rules: [
     {
       ...
     },
     {
        test: /\.less$/,
        use: ['style-loader', 'css-loader','less-loader'] 
            // 1 先使用less-loader去调用less,将less处理成css
            // 2 使用css-loader将css变成js能处理的模块
            // 3 交给style-loader,将css放入html的head元素中
     },
  ]

4.browserslistrc使用

browserslistrc功能:

/**
 * 1 工程化
 * 2 兼容性: CSS JS       --> 前缀处理展示网站:http://autoprefixer.github.io/
 * 3 如何实现兼容?         --> Autoprefixer、post-preset-env、postcss    babel
 * 4 到底兼容那些平台?     --> 兼容市面上一些主流的浏览器平台  caniuse.com  各种浏览器使用占比:https://caniuse.com/usage-table
 * 
 * 
 * >1%                  市场占有率大于1%
 * default              市场占有率大于0.5%,采用最新的两个版本,firefix,not dead
 * dead                 24个月没有官方支持更新的浏览器,就代表死掉了
 * last 2 versions      浏览器最新的两个版本
 */

在package.json中配置browserslist:

{
  ...
  "browserslist":[
    "> 1%",
    "last 2 versions",
    "not ie <= 8",
    "not dead"
  ]
}

或者在项目根目录下新建.browserslistrc配置文件:

> 1%
last 2 version
not dead
not ie <= 8

5.postcss使用

#12345678是rgba的模式
postcss简述:

1 postcss 是什么:通过javascript转换样式的工具
2 less(less-loader) --> css --> css-loader
3 postcss-preset-env    集合了很多的现代css转换所需要的插件
4 postcss 功能:做一些css样式兼容性的操作,如 给样式针对浏览器添加不同的前缀、给css样式的重置处理
5 使用autoprefixer + browserslistrc + postcss 即可给css样式代码的前缀做兼容性处理

安装postcss:

yarn -D add postcss

如果要在命令行中直接使用npx postcss,还需要安装postcss-cli:

yarn -D add postcss-cli

安装autoprefixer:

yarn -D add autoprefixer

安装工具功能说明:

postcss 类似于一个处理css的转换工具平台
postcss-cli 让postcss可以直接在命令行中使用
autoprefixer 根据.browserslistrc提供的兼容条件,给css样式正对不同浏览器添加前缀

命令工具使用:

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

postcss-loader处理流程:

postcss 需要在css-loader 之前对css对兼容性处理

css-loader 将css变成模块

style-loader 将css放入html中

在webpack.config.js配置postcss-loader:

module: {
      rules: [
         {
            test: /\.css$/,
            use: [
               'style-loader',
               'css-loader',
               {
                  loader: 'postcss-loader',
                  options:{
                     postcssOptions:{
                        plugins:[
                           // require('autoprefixer'),
                           // require('postcss-preset-env'),
                           // postcss-preset-env 已经包含了 autoprefixer
                           // 可简写 
                           'postcss-preset-env'
                        ]
                     }
                  }
               }]
         }
      ]
   }

使用postcss.config.js单独配置插件信息:

module.exports = {
    plugins:[
        require('postcss-preset-env')
    ]
}

然后webpack.config.js的配置文件可简写了:

 module: {
      rules: [
         {
            test: /\.css$/,
            use: [
               'style-loader',
               'css-loader',
               'postcss-loader',
            ]
         },
         {
            test: /\.less$/,
            use: [
               'style-loader',
               'css-loader',
               'postcss-loader',
               'less-loader'
            ]
         },
      ]
   }

6.importLoaders

问题:
by.css:

@import './test.css';

.title{
    border: solid 20px #12345678; 
}

test.css:

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

test部分的css不会被postcss-loader处理
问题溯源:
image.png

使用importLoaders:

 {
    test: /\.css$/,
    use: [
       'style-loader',
       {
          loader: 'css-loader',
          options:{
             importLoaders: 1 // importLoaders的作用是决定@import模块在使用css-loader前,要使用几个其它的loaders处理。
          }
       },
       'postcss-loader',
    ]
 }

7.file-loader处理图片

a.加载图片资源

file-loader在webpack.config.js中的配置:

const path = require('path')

module.exports = {
   entry: './src/main.js',
   output: {
      path: path.resolve(__dirname, 'dist'), // 这里必须要配置为绝对路径
      filename: 'bundle.js',
      publicPath: '/dist/'
   },
   module: {
      rules: [
         ...
         {
            test: /\.(png|jpg|gif)$/,
            use: [{
               loader: 'file-loader',
               options: {
                  esModule: false // 不转为 esModule
               }
            }]
         }
      ]
   }
}

创建一个处理img的js:

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

    // 02 创建一个img元素
    const oImg = document.createElement('img');
    oImg.src = require('../img/01.png').default; // 不使用default时,需要配置file-loader参数
    oEle.appendChild(oImg);
    
    return oEle;
}

document.body.appendChild(packImg());

使用esModule的方式导入,则不用.default:

import oImgSrc from '../img/01.png';

oImg.src = oImgSrc;

css-loader会将url替换成require,进而被打包成es模块语法
配置:

{
    test: /\.css$/,
    use: [
       'style-loader',
       {
          loader: 'css-loader',
          options: {
             importLoaders: 1, // importLoaders的作用是决定@import模块在使用css-loader前,要使用几个其它的loaders处理。
             esModule:false  // css中导入图片时,会自动将url图片引入变成require语法,进而编译成esMoudule语法,这样就会报错,所以需要设置为false
          }
       },
       'postcss-loader',
    ]
 },

图片资源导入总结:

/**
 * 打包图片:
 *  - img src
 *      + 使用 require 导入图片,此时如果不配置 esModule:false,则需要 .default
 *      + 也可以在配置中设置 esModule:false
 *      + 使用 import 导入图片,此时不需要 .default
 *  - background url
 *      + 需要直接返回资源,不需要转成 seModule, 不需要 .default,在css-loader中需要配置 esModule:false
 */
b.设置图片名称与输出tscproj

处理出片名称配置:

{
    test: /\.(png|jpg|gif)$/,
    use: [{
       loader: 'file-loader',
       options: {
          name: '[name].[hash:6].[ext]', //  name: 'imgs/[name].[hash:6].[ext]', 这样配置,则不需要再配置outputPath了
          outputPath:'imgs/'
       }
    }]
 }
]

设置图片名称常用占位符:

/**
 * [ext]: 源文件扩展名
 * [name]: 文件名
 * [hash]: 文件内容的的hash值
 * [contenthash]: 文件内容的hash值
 * [hash:<length>]: 只取hash的前length位
 * [path]: 文件路径
 */

8.url-loader处理图片

简述url-loader功能:

url-loader:
 优点:将图片转为base64编码,可以内嵌到html或css中,减少http请求
 缺点:图片转base64编码后,大小会变大,文件大小约为原来的1.3倍,浏览器可以使用的文件大小有限制。
       图片很大时,网页的显示将变慢
       资源不会被浏览器缓存,每次访问都要重新获取

使用url-loader后的配置:

{
    test: /\.(png|jpg|gif)$/,
    use: [{
       loader: 'url-loader',
       options: {
          name: '[name].[hash:6].[ext]', //  name: 'imgs/[name].[hash:6].[ext]', 这样配置,则不需要再配置outputPath了
          outputPath: 'imgs/',
          limit: 10 * 1024
       }
    }]
 }

url-loader与file-loader的区别与联系:

区别:
   url-loader:将图片编码,直接放入css或html中
   file-loader:复制图片,放入dist目录下的指定目录中,资源分开请求
 
联系:
    配置参数基本相同
    url-loader 内部可以调用file-loader,根据limit值,决定是否复制图片或者将图片编码

理解图片Base64编码数据格式参考:https://www.jianshu.com/p/c42...

9.asset处理图片

asset type module是webapck5的内置处理方法
a.处理图片

功能介绍:

/**
 * asset module type
 * 01 asset/resource => file-loader     目标资源拷贝
 * 02 asset/inlinet  => url=loader      目标资源内联
 * 03 asset/source   => raw-loader      目标资源源码
 * 04 asset/控制使用loader               目标资源控制使用loader
 */

使用asset处理图片资源的asset/resource配置(可全局或局部设置asset模块处理过的文件):

module.exports = {
   ...
   output: {
      ...
      // assetModuleFilename: 'assets/[name].[hash:4][ext]'   // 全局设置asset模块处理的文件存放位置{这里的[ext]包含了'.'如:'.png}
   },
   module: {
      rules: [
         ...
         {
            test: /\.(png|jpg|gif)$/,
            type:'asset/resource',
            generator:{
               filename:'imgs/[name].[hash:4][ext]',
            }
         }
      ]
   }
}

asset/inline配置:

{
    test: /\.(png|jpg|gif)$/,
    type:'asset/inline',
 }

asset配置:

{
    test: /\.(png|jpg|gif)$/,
    type: 'asset',
    generator: {      // 做拷贝时的命名规则
       filename: 'imgs/[name].[hash:4][ext]',
    },
    parser:{          // 设置做拷贝的条件
       dataUrlCondition:{
          maxSize:10*1024      // 小于该值时,做dataURL
       }
    }
 }
b.处理图标字体

创建一个处理图标字体的js:

import '../font/iconfont.css';
import '../css/index.css';  // 定义icon的样式

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

    const oSpan = document.createElement('span');
    oSpan.className = 'iconfont icon-music lg-icon';  // lg-icon 用来控制icon样式

    oEle.appendChild(oSpan);
    return oEle;
}

document.body.appendChild(packFont());

配置asset,让其能处理图标字体文件:

 {
    test: /\.(woff2?|eot|ttf|otf)$/,
    type:'asset/resource',      // 图标字体文件,只需要拷贝到dist目录即可
    generator: {
       filename:'font/[name].[hash:3][ext]'
    }
 }
阅读 372
10 声望
0 粉丝
0 条评论
10 声望
0 粉丝
文章目录
宣传栏