webpack中模块加载器Loader、插件plugins、optimization属性

news2025/1/16 19:05:10

目录

模块加载器(Loader)

导入css文件

加载图片

方法一

方法二

转换es6(向下兼容es5)

html代码组件导入导出

导入less文件

自定义loader(Markdown文件加载器)

markdown-loader.js文件

webpack.config.js文件配置

插件(plugins)

清除dist目录插件

通过html-webpack-plugin插件生成html(自动引入js代码)

copy-webpack-plugin

替换内容(DefinePlugin)

分离css文件

压缩css文件

自定义插件

自定义插件作用

webpack钩子链接

optimization属性

Tree-shaking(去掉无代码)

提取公共模块配置

Scope Hoisting(作用域提升)

sideEffects(副作用)

压缩css文件


模块加载器(Loader)

webpack内部默认只会处理解析JavaScript文件,需要通过模块加载器来处理其它类型文件例如css、图片等文件。

注意use下的loader会从后往前依次执行,例如下面代码先执行css-loader后执行style-loader。

const path = require('path')
module.exports = {
  entry: {
    main: ['./src/main.js', './src/index.js']
  },
  mode: 'development',
  output: {
    filename: '[name]-bundle.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'dist/'
  },
  devServer: {
    contentBase: 'dist',
    overlay: true,
    port: 8080,
    open: true
  },
  module: {
    rules: [
      // es6转换(向下兼容es5)
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
            loader: 'babel-loader'options: {
                presets: ['@babel/preset-env'] // @babel/preset-env包括es6的全部特性转换
            }
        }
      },
      // 分离css文件
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          }
        ]
      },
     // 加载图片 超过10KB的png图片使用file-loader处理,10KB内的用url-loader处理
     {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'file-loader'
          }
        ]
      },
     {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
                limit: 10 * 1024,  // 10KBname:'[name].[ext]',
                publicPath:'images/',
                outputPath:'images/'
            }
          }
        ]
      },
      // html代码组件导入导出
      {
        test: /\.html$/i,
        use: [
          {
            loader: 'html-loader',
            options: {
                attrs: ['img:src','a:href']
            }
          }
        ]
      },
    ]
  },
  plugins: []
}

导入css文件

在src文件夹下创建main.css在main.js中通过require('./main.css')引入,命令行输入npm install style-loader css-loader -D安装css-loader(能识别CSS并加载,支持模块化、压缩、文件导入等特性)和style-loader(通过动态创建style标签的方式,让解析后的css内容能够作用到页面中)。然后将webpack.dev.js图中注释内容打开即可(test是通过正则表达式匹配文件,use中为使用的loader),再次运行webpack-dev-server --config=config/webpack.dev.js便可以在http://localhost:8080/中看到添加了css的index.html文件

加载图片

方法一

拷贝文件加载原图片file-loader。

方法二

通过url-loader将图片转换为base64字符串格式

通常搭配使用小文件使用Data URLs,减少请求次数。大文件单独提取存放,提高加载速度。

命令行输入npm install url-loader file-loader -D,配置如上代码。

这时可以在css和less文件中使用图片,(这里的图片会被默认转换为base64字符串格式,好处是浏览器不用发送请求了,直接可以读取,坏处是图片如果太大,会导致转换后体积增大30%,所以这里设置了大小限制limit,表示当大于10kb时,在dist文件夹中创建images文件夹,在该文件夹下生成图片,通过链接导入,小于时才会base64转换),

注意css和less文件中使用图片的地址是src下的图片和文件的相对地址,而html中img标签使用的地址是publicPath(静态资源的引用路径)

转换es6(向下兼容es5)

babel是一个平台,需要配置插件去完成具体特性的转换。

所以babel-loader依赖@babel/core模块且和需要完成具体特性转换插件例如@babel/preset-env(包括es6所有的特性转换)。

命令行输入npm install -D babel-loader @babel/core @babel/preset-env,配置如上代码.

此时如果在main.js写了es6的语法会被转换成es5(在最后的输出文件main-bundle.js可以查看)。

html代码组件导入导出

使用html-loader后下面的head.html文件,可以像js代码一样导入导出使用

<head><imagesrc=""mode="" /></head>

命令行输入npm install -D html-loader,配置如上代码。

注意html引入的资源中默认只会对image中的src链接进行处理,如果是a标签链接本地图片会无法展示,可以通过opttions下的attrs中添加a:href对a标签的图片链接进行处理解决。

导入less文件

less是css预处理文件,引入了变量函数等是css处理更灵活。首先命令行输入npm install less less-loader -D,然后在src文件夹下创建header.less文件,在main.js中写入require('./header.less'),然后配置webpack.config.js,在rules数组中添加{test: /\.less$/i,use: ["style-loader","css-loader","less-loader",],},注意这里还是会生成style标签插入,想要分离出来,把"style-loader"替换为{loader:MiniCssExtractPlugin.loader},这时less文件也会被分离到index.css中(见分离css文件)

自定义loader(Markdown文件加载器)

注意use下loader处理的最后结果需要是一个字符串的导出,如果最后一个处理的loader是自定义loader,则需要返回的结果如下

return'module.export = "xxx"'return'export default "xxx"'

这样webpack最后处理将外层括号去掉,通过import 导入的自定义loader处理的文件,导入的内容就为xxx。

markdown-loader.js文件

需要安装marked包解析md文件的输入内容

const marked = require('marked')
module.exports = source => {
  // 将md文件内容转换为字符串const html = marked(source) 
  // JSON.stringify转换字符串中的换行符和引号 例如将”转为\"// 方法一:只经过自定义loader处理  return`module.export = ${JSON.stringify(html)}`// return `export default ${JSON.stringify(html)}`// 方法二: 返回的值再经过html-loader处理// return html
}

webpack.config.js文件配置

const path = require('path')
module.exports = {
  entry: {
    main: ['./src/main.js', './src/index.js']
  },
  mode: 'development',
  output: {
    filename: '[name]-bundle.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'dist/'
  },
  devServer: {
    contentBase: 'dist',
    overlay: true,
    port: 8080,
    open: true
  },
  module: {
    rules: [
      // 自定义markdown-loader
      {
        test: /\.md$/,
        use: {
            loader: './markdown-loader'// 自定义loader:markdown-loader.js文件路径
        }
        // 方法二 //use: [//  { loader: 'html-loader' },//  { loader: './markdown-loader' }//]
      }
    ]
  },
  plugins: []
}

注意方法二是将返回的html交给html-loader处理,故use下数组中的顺序不能反。

方法二转换过程

638f15d768bf7aa7451587390e671c4c.png

插件(plugins)

清除dist目录插件

每次webpack打包文件会覆盖dist文件,之前留下的文件不会去删除,所以打包时需要先手动清空dist文件夹,然后在生成打包的文件。

命令行输入npm install clean-webpack-plugin -D,在webpack.dev.js中输入const { CleanWebpackPlugin } = require('clean-webpack-plugin'),然后在plugins数组(和module属性同级的属性)中添加new CleanWebpackPlugin()即可,这时我们每次输入命令行webpack --config=config/webpack.dev.js后都会先清空dist文件夹,然后在生成打包的文件。

通过html-webpack-plugin插件生成html(自动引入js代码)

运行命令行npm install html-webpack-plugin -D安装插件,配置webpack.dev.js中写入const HtmlWebpackPlugin = require('html-webpack-plugin')用于引入自动生成html的插件,给module.export指向的对象添加属性plugins: [new HtmlWebpackPlugin({ template: './src/index.html', title: 'example', meta: {viewport:'width=device-width' }}),new HtmlWebpackPlugin({filename:'about'})]

  • template指定的模板便是移入src文件夹下的index.html的路径,在模板中可以通过<%= htmlWebpackPlugin.options.title %>访问example。

每个实例(new HtmlWebpackPlugin)都会生成一个html文件,上面会生成一个index.html和about.html文件。每个文件都会自动引入打包好的js文件.

注意如果webpack.config.js文件是在config文件夹下,但是这里的相对路径./依然指的是项目路径即config的上层路径。最后运行webpack --config=config/webpack.dev.js后会在dist文件上生成一个index.js文件,该文件中会自动引入main-bundle.js即打包后的出口文件(不需要手动引入了,可以去掉output下的publicPath: 'dist/'属性)。

  • chunks:当有多个打包的html且有多个输出js文件,默认每个打包文件会引入多个输出js文件,可以通过chunks属性只引入指定的js文件。如下图只引入的对应的js文件。

copy-webpack-plugin

用来将静态文件(一般为public目录下内容)复制到输出文件夹下。

plugin的数组中添加new CopyWebpackPlugin(['public']),这里的public为需要复制的文件夹。

替换内容(DefinePlugin)

DefinePlugin为webpack的内置插件。const webpack=require('webpack'),plugins中添加new webpack.DefinePlugin({API_BASE_URL:'"Example Domain"'}),此时 在代码中的API_BASE_URL将会替换成"Example Domain"。

注意需要用单引号包括双引号,替换时会去掉外层的一层引号(可以使用JSON.stringify('Example Domain')去转换)

分离css文件

当css文件比较大时可以提取为一个文件通过link的方式引入(当css文件比较小时不适合,不提取为单独的文件可以减少http的请求)

命令行输入npm install mini-css-extract-plugin -D安装分离插件,在webpack.dev.js中输入const MiniCssExtractPlugin = require('mini-css-extract-plugin'),将之前配置style-loader的对象替换为{loader:MiniCssExtractPlugin.loader},最后在plugins的数组中添加new MiniCssExtractPlugin({filename:'./index.css'})即可,filename代表分离出来的css名字和地址,这里注意./表示的位置是dist文件夹下。

压缩css文件

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')然后在plugins的数组中添加new OptimizeCssAssetsWebpackPlugin()即可。

注意通常不推荐配置在plugins中,因为这样会在任何情况都使用,可以通过配置在optimization中使其只有在production环境下打包使用

自定义插件

webpack的插件需要是一个函数或者一个包含apply方法的对象。通过在生命周期的钩子中挂载函数实现扩展功能。

自定义插件作用

清除打包后文件中的注释。

webpack钩子链接

Compiler Hooks | webpack

classMyPlugin {
  // compile中包含此次构建的所有信息。 apply(compiler) {
    // emit钩子在webpack即将输出文件之前执行
    compiler.hooks.emit.tap("MyPlugin", compilation => {
      // MyPlugin为插件的名称,compilation理解为此次打包的上下文// compilation.assets下是一个数组包含了所有经过webpack打包后的文件信息;for(const name in compilation.assets) {
        // 判断文件名是否以.js结尾if(name.endsWith('.js')){
          const contents = compilation.assets[name].source()
          // 取出文件内容,将注释去掉const withoutComments = contents.replace(/\/\*\*+\*\//g, '')
          // 修改新的文件信息,注意source和size属性要同步修改
          compilation.assets[name] = {
            source: () => withoutComments,
            size: () => withoutComments.length
          }
        }
      }
    })
  }
}

配置:申明上面文件后在plugins的数组中添加new MyPlugin()即可

optimization属性

用于优化输出的文件,通过在module.exports对象中添加属性optimization配置。

Tree-shaking(去掉无代码)

在webpack --mode production时会被自动调用。配置optimization: {useExports:true,minimize:true}实现,这两个属性只针对ES Module生效。

useExports:打包只导出外部使用过的成员。

minimize: 移除未被外部使用的成员。

注意:由Webpack打包的代码必须使用ES Module而不是commonjs(当配置了babel转换为commonjs时上面2个属性即使配置了也不会生效故通常可以设置modules:false来关闭转换)。

提取公共模块配置

当有多入口文件生成多个打包文件时,如果入口文件中都用到jQuery,需要都引入,这时打包文件会重复打包jquery,在的module.exports对象中添加属性optimization: {splitChunks: {chunks: 'all'}},这时便会提取公共模块配置。不会重复打包重复的模块。

Scope Hoisting(作用域提升)

设置concatenateModules:true。

尽可能的将所有模块合并输出到一个函数中。

sideEffects(副作用)

在webpack --mode production时会被自动调用。模块执行时除了导出成员之外所作的事情。

设置sideEffects:true开启功能并在package.json文件中添加sideEffects:false标识代码没有副作用,才可以生效使文件中只有被导出的文件才会被执行。

注意副作用是包括直接引入css文件或未导出成员仅执行代码。开启过后下面代码将会被去除。

import'./global.css'import'./preset.js'

可以通过在package.json中添加属性"sideEffects":["./src/preset.js","*.css"] 来保留。

压缩css文件

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')后在optimization属性下添加minimizer:[new OptimizeCssAssetsWebpackPlugin()]即可。

注意这样表示我们要自定义压缩器,会覆盖webpack内置的js压缩器,所以此时js文件将不会被压缩了,我们通过const TerserWebpackPlugin = require('terser-webpack-plugin')引入,然后在数组中添加new TerserWebpackPlugin()即也可以压缩js文件了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/145121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】程序的翻译过程(图示详解)

因为淋过雨&#xff0c;所以懂的为别人撑伞&#xff1b;因为迷茫过&#xff0c;所以懂得为别人指路。 我们都知道写好代码后&#xff0c;编译器会帮助我们把代码生成可执行程序&#xff0c;细加了解又会知道程序的生成又分为四步&#xff1a;预处理、编译、汇编、链接。那么这四…

STM32MP157驱动开发——Linux IIO驱动(上)

STM32MP157驱动开发——Linux IIO驱动&#xff08;上 &#xff09;0.前言一、IIO 子系统简介1.iio_dev 结构体2.iio_dev 申请与释放3.iio_dev 注册与注销4.iio_info5.iio_chan_spec二、驱动开发1. ICM20608 的 IIO 驱动框架搭建2.IIO 设备申请与初始化3.基于以上驱动框架开发 I…

[JavaEE初阶] 线程安全问题的原因和解决方案

努力努力,月薪过亿!!! 格局打开~~~ 文章目录前言1. 线程安全问题的概念2. 线程安全问题的原因3. 线程安全问题解决--加锁3. synchronized4. 死锁4.1 产生死锁的情况4.3 产生死锁的必要条件4.4 避免死锁的方法前言 线程安全这里可能会出道面试题,在日常工作中也是很重要的内容.…

MathType公式对齐不正确

MathType公式对齐不正确1.软件环境⚙️2.问题描述&#x1f50d;3.解决方法&#x1f421;4.1.通过标尺对齐4.2.通过输入具体的制表符位置对齐1.软件环境⚙️ Windows10 教育版64位 Word 2021 MathType 7 2.问题描述&#x1f50d; 在使用Word写论文的时候&#xff0c;总是避免不…

JavaScript 模块:理解模块系统

前言 现代JavaScript开发毋庸置疑会遇到代码量大和广泛使用第三方库的问题。解决这个问题的方案通常需要把代码拆分成很多部分&#xff0c;然后再通过某种方式将它们连接起来。 在ECMAScript 6模块规范出现之前&#xff0c;虽然浏览器原生不支持模块的行为&#xff0c; 但也迫…

ssh连接ubuntu报错

记录问题&#xff1a;1我在本机windows用ssh rootubuntu连接失败 显示端口21啥的2 打开Ubuntu系统&#xff0c;输入ps -e|grep ssh&#xff0c;发现只有agent&#xff0c;没有server3 安装ssh server&#xff0c;输入sudo apt-get install openssh-server&#xff0c;发现报错信…

仅需一个注解,实现 SpringBoot 项目中的隐私数据脱敏!

这两天在整改等保测出的问题&#xff0c;里面有一个“用户信息泄露”的风险项&#xff08;就是后台系统里用户的一些隐私数据直接明文显示了&#xff09;&#xff0c;其实指的就是要做数据脱敏。数据脱敏&#xff1a;把系统里的一些敏感数据进行加密处理后再返回&#xff0c;达…

一键自动化 | Salesforce发布Automation Anywhere自动化组合!

2022年12月1日&#xff0c;Salesforce推出了一个新的Automation Everywhere Bundle&#xff0c;以加速端到端的工作流编排&#xff08;Workflow Orchestration&#xff09;、跨系统自动化&#xff0c;以及在任何地方嵌入数据和AI驱动的工作流。 该捆绑包完全集成到Salesforce F…

acwing第84场周赛(4788,4789,4890)题解

4788. 最大数量 某商场在一天中一共来了 nn 个客人。 每个客人进入商场的具体时刻&#xff08;精确到分钟&#xff09;已知。 请你计算并输出在同一时刻&#xff08;精确到分钟&#xff09;进入商场的最大客人数量。 输入格式 第一行包含整数 nn。 接下来 nn 行&#xff…

二叉搜索树比起二叉树又有什么不一样呢?

二叉搜索树比起二叉树又有什么不一样呢&#xff1f;&#x1f3d0;什么是二叉搜索树&#x1f3d0;二叉搜索树的实现&#x1f3c0;节点类:&#x1f3c0;构造函数&#x1f3c0;析构函数&#x1f3c0;插入insert⚽非递归版本⚽递归版本&#x1f3c0;查找find⚽非递归版本⚽递归版本…

spring boot 八:SpringBoot响应返回xml数据

spring boot 八&#xff1a;SpringBoot响应返回xml数据 1 前言 根据DispatcherServlet源码分析&#xff0c;研究SpringBoot的Controller返回xml数据的一些方法&#xff0c;包含单独配置和全局配置返回xml数据两种方式。 依赖的SpringBoot版本&#xff1a; <parent>&l…

u盘有病毒怎么办?修复U盘,3个方法解决

U盘和外部的驱动器相比&#xff0c;它的体积更小&#xff0c;携带更加方便&#xff0c;可以轻松地与他人分享文件。虽然U盘使用很方便&#xff0c;但是有时会出现中病毒的情况。u盘有病毒怎么办&#xff1f;如果您也受到此问题的影响&#xff0c;我们可以提供一种有效的方法来修…

物联网架构实例—Ubuntu 安装Redis

1.准备更新apt-get源sudo apt-get update2.安装执行Redis 安装命令sudo apt-get install redis-server3.检查安装状态sudo /etc/init.d/redis-server status查看Redis运行进程ps -aux|grep redis4.将Redis添加到服务器启动项修改/etc/rc.localvim /etc/rc.local将下面的命令加到…

阿里云办公安全产品专家高传贵:零信任,让全球办公安全更简单

2022 年 8 月 30 日&#xff0c;阿里云用户组&#xff08;AUG&#xff09;第 9 期活动在北京举办。活动现场&#xff0c;阿里云办公安全产品专家高传贵&#xff0c;向参会企业代表分享了零信任&#xff0c;让全球办公安全更简单。本文根据演讲内容整理而成。 大家下午好。我今天…

内部类导致的内存泄漏

前两天刷文章偶然翻到一篇因使用非静态内部类时导致内存泄漏的问题,出于好奇自己也动手一试 什么叫内存泄漏 内存泄漏&#xff08;Memory Leak&#xff09;是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放&#xff0c;造成系统内存的浪费&#xff0c;导致程序…

WuThreat首个发布全球领先的身份安全云产品ITDR Cloud

随着数字化、人工智能&#xff0c;公有/私有云&#xff0c;物联网络及5G等技术的全面普及和迭代更新&#xff0c;身份管理建设作为企业重要的基础设施。然而现在黑客攻击手段复杂多样&#xff0c;在历年的实战攻防演习中有大量的应用系统与基础设施的的身份入口被攻破&#xff…

【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】

本文将使用一个来自NASA测试不同飞机机翼噪音的数据集&#xff0c;通过梯度下降、随机梯度下降、小批量随机梯度下降这3种优化算法进行模型训练&#xff0c;比较3种训练结果的差异。 目录1. 梯度下降、随机梯度下降、小批量随机梯度下降区别2. 读取训练数据3. 从零实现3种梯度算…

多线程与高并发(16)——线程池原理(ThreadPoolExecutor源码)

本文从ThreadPoolExecutor源码来理解线程池原理。 ThreadPoolExecutor使用了AQS、位操作、CAS操作等。在看这篇文章之前&#xff0c;需要具备以下知识&#xff1a; 多线程与高并发&#xff08;6&#xff09;——CAS详解&#xff08;包含ABA问题&#xff09; 多线程与高并发&…

腾讯三面:进程写文件过程中,进程崩溃了,文件数据会丢吗?

进程写文件&#xff08;使用缓冲 IO&#xff09;过程中&#xff0c;写一半的时候&#xff0c;进程发生了崩溃&#xff0c;会丢失数据吗&#xff1f; 答案&#xff0c;是不会的。 因为进程在执行 write &#xff08;使用缓冲 IO&#xff09;系统调用的时候&#xff0c;实际上是…

企业宣传片制作配音,我们该从哪里找?

优秀的品质的配音是制作优质企业视频必不可少的硬件条件。因此&#xff0c;许多公司视频配音或旁白声音是由专门从事配音行业的人员配音的。 首先是在宣传视频中配音的作用 1.宣传视频的配音为您建立企业形象 2.宣传视频的配音将为您打开市场 3.宣传视频的配音将使您的宣传…