当前位置:主页 > 查看内容

Webpack知识整理——资源加载器

发布时间:2021-05-19 00:00| 位朋友查看

简介:Webpack知识整理-资源加载器 前端模块化概述 模块化打包工具 WebPack 快速上手 webpack 配置文件 设置打包的入口和出口 三种打包模式 资源模块加载 样式资源加载 文件资源加载器 URL 加载器 babel-loader 处理新特性 Webpack 加载资源的方式 html加载器处理……

前端模块化概述

提到前端的模块化,很多朋友第一时间想到的就是 AMD ,CMD, CommonJS 以及 ES Modules这些。
不过,这些都是js文件的模块化,而一个前端项目并不是只有js文件。
一个前端项目中,除了js文件 还有html,css,图片字体等等各种文件,既然是前端模块化,那么所有的前端资源都需要模块化

总结一下我们前端项目模块化,需要支持以下几个功能:

  1. ES新特性代码编译
  2. 模块化JS打包
  3. 支持不同类型的资源进行模块化打包

模块化打包工具

前端的模块化打包工具,常见的有 webpack , rollup , parcel

  • webpack
    它的核心特性就能很好的满足上面我们的需求,它为处理资源管理和分割代码而生,可以包含任何类型的文件。灵活,插件多。

  • rollup
    用标准化的格式(es6)来写代码,通过减少死代码尽可能地缩小包体积。

  • parcel
    超快的打包速度,多线程在多核上并发编译,不用任何配置。

打包工具解决的是前端整体的模块化,并不单指 JavaScript 模块化

WebPack

快速上手

webpack 依赖node环境运行,首先保证已经安装了node
然后在项目中安装对应的包 webpack 和 webpack-cli
安装包可以使用npm 或者 yarn
具体区别体现在运行上:

  • 如果是npm安装 webpack 和 webpack-cli ,安装成功后想要运行,需要在package.json的 script 里加入对应的执行脚本
    npm install webpack webpack-cli -D
  • 如果是通过yarn安装 则不需要再手动添加
    yarn add webpack webpack-cli --dev

默认的约定
直接执行webpack 会默认把当前项目中 src 目录下的 index.js 打包到 dist 目录下 生成 main.js
并且webpack 默认自带处理ES Moudules语法的功能

webpack 配置文件

设置打包的入口和出口

上面我们说到,默认的打包目录。这个目录是可以通过项目根目录中的 webpack.config.js 这个文件进行修改的。

module.exports = { 
	entry: './src/main.js',
	output: { 
		filename: 'bundle.js',
		path: path.join( __dirname )
	 }	
}
  • entry 设置打包的文件入口
  • output 设置打包到哪去。 filename 是打包后生成的文件名,path是存放的路径。

三种打包模式

在我们执行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.

意思就是说,让我们去设置打包的模式。webpack的打包模式有三种:

  1. none 无
  2. development 开发环境模式
  3. production 生长环境模式

设置打包模式可以通过两种方式:

  • 通过cli命令 比如 webpack --mode development
  • 还可以在 webpack.config.js 配置文件中设置
	module.exports = {
	    mode: 'development',
	    entry: './src/index.js',
	    output: {
	        filename: 'bundle.js',
	        path: path.join(__dirname, 'dist/')
	    }
	}

资源模块加载

如果要想让webpack处理资源模块的打包,那么各种文件对应的loader就必不可少,Loader是webpack的核心特性。
借助于Loader就可以加载任何类型的资源。
加载器大致可以分成三类:

  1. 编译转化类 比如 css-loader
  2. 文件操作类 比如 file-loader
  3. 代码检查类 比如 eslint-loader

样式资源加载

如果我们现在为项目中添加了css文件,也想通过webpack进行打包
在这里插入图片描述
那么此时运行webpack打包就会出现报错

ERROR in ./src/style/index.css 1:5
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

这是报错中的 You may need an appropriate loader to handle this file type 这句 意思就是说 你可能需要一个loader来处理这种类型的文件。

比如上面的 css 文件 我们可以借助于 style-loader 和 css-loader 其中 style-loader的作用是把样式添加到dom中, css-loader是用于把css打包到bundle.js中 ( 其实就是读取样式文件内容 转化字符串记录在数组或者对象中 )

	module.exports = {
	    mode: 'none',
	    entry: './src/index.js',
	    output: {
	        filename: 'bundle.js',
	        path: path.join(__dirname, 'dist/')
	    },
	    module: {
	        rules: [
	            {
	                test: /.css$/,
	                use: ['style-loader', 'css-loader']
	            }
	        ]
	    }
	}

在webpack.config.js 中添加module属性 在rules数组里,每一个成员对应了一种需要通过loader处理的文件类型。
test用于匹配对应后缀名的文件, use 表示要使用的loader 这里loader的使用顺序是不能乱写的 要遵循从后往前调用的原则。

webpack不仅仅是可以让我们在js中引入css代码,它建议我们引入任何类型,我们当前代码需要的资源文件

真正需要这些资源的不是应用,而是我们当前编写的代码。

文件资源加载器

如果是一些图片资源在js中导入,webpack的处理原理如下:
在这里插入图片描述
其实就是把对应文件复制到了打包结果目录中,同时把该文件的路径导入到了bundle.js中。

我们使用的Loader是 file-loader, 打包后的图片文件会默认以网站根目录的路径进行导入,如果需要指定文件夹需要在output中配置publicpath

	import icon from './assets/icon.png'
	let img = new Image()
	img.src = icon
	document.body.append(img)
	module.exports = {
	    mode: 'none',
	    entry: './src/index.js',
	    output: {
	        filename: 'bundle.js',
	        path: path.join(__dirname, 'dist/'),
	        publicPath: 'dist/'
	    },
	    module: {
	        rules: [
	            {
	                test: /.css$/,
	                use: ['style-loader', 'css-loader']
	            },
	            {
	                test: /.png$/,
	                use: ['file-loader']
	            }
	        ]
	    }
	}

URL 加载器

这里的url 加载器 指的就是 url-loader, 这个loader的作用可以把资源文件转化为Data URL。 一旦文件转为data url之后 dist目录中就不会复制文件了。
我们可以通过一些参数来设置一个值,让超过这个值大小的文件 依然以file-loader处理 ,小于这个值的文件转为data url
要想使用 url-loader 我们需要先安装file-loader

	module.exports = {
	  mode: 'none',
	  entry: './src/main.js',
	  output: {
	    filename: 'bundle.js',
	    path: path.join(__dirname, 'dist'),
	    publicPath: 'dist/'
	  },
	  module: {
	    rules: [
	      {
	        test: /.css$/,
	        use: [
	          'style-loader',
	          'css-loader'
	        ]
	      },
	      {
	        test: /.png$/,
	        use: {
	          loader: 'url-loader',
	          options: {
	            limit: 10 * 1024 // 10 KB 超过10kb的就还是用file-loader 复制文件 引入路径
	          }
	        }
	      }
	    ]
	  }
	}

babel-loader 处理新特性

webpack 默认只能处理模块化的语法,因为它本身就是为了实现模块打包的,但是它并不支持所有的新特性,所以我们需要借助于babel-loader 来处理js代码中的新特性
需要安装 三个包

"@babel/core","@babel/preset-env", "babel-loader"
      {
        test: /.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }

Webpack 加载资源的方式

  • 遵循 ES Modules 标准的 import 声明
  • 遵循 CommonJS 标准的 require 函数
  • 遵循 AMD 标准的 define 函数和 require 函数
  • 所有样式代码中的 @import 指令和 url 函数
  • HTML 代码中图片标签的 src 属性
html加载器,处理标签内资源引用

处理html文件中的src属性 或者 a 标签的href属性 ,需要借助于 html-loader

      {
        test: /.html$/,
        use: {
          loader: 'html-loader',
          options: {
            attrs: ['img:src', 'a:href'] // 表示要处理的src 和 href
          }
        }
      }

编写一个转化md为html的loader

Loader 负责资源文件从输入到输出的转换,webpack要求输出的必须要是js的代码,我们可以对于同一个资源依次使用多个 Loader 处理

loader代码

const marked = require('marked')
// source 接收所有的匹配到的资源内容
module.exports = source => {
    return marked(source)
}

webpack.config.js 代码

            {
                test: /.md$/,
                use: [
                    'html-loader',
                    './src/loader/md_loader.js'
                ]
            }

导入md的代码

import './style/index.css'
import noteStr from './note.md'
const noteDiv = document.createElement('div')
noteDiv.innerHTML = noteStr
document.body.append(noteDiv)
;原文链接:https://blog.csdn.net/fanfanyuyu/article/details/115462890
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐