Webpack系列之核心概念

175 阅读6分钟

Webpack本质上是一个Javascript应用程序的静态模块打包器(module bundler),当应用程序经Webpack处理时, 会从入口文件开始,递归地构建整个应用所依赖的关系图,其中包含应用程序需要的每个模块;然后将所有这些模块打包成一个或多个bundle文件.

Webpack核心概念

Webpack是一个打包模块化Javascript工具,在Webpack里一切文件(html、js、jsx、less、css、图片)皆模块,进Webpack对模块组合打包处理后生成浏览器能直接使用的静态资源;通俗的说想要使用Webpack,就需要搞明白Webpack的打包原理,以及各个配置项的含义跟使用规则;Webpack主要核心概念包括entryoutputmoduleresolveplugins等;

image-20210316205644429

全局安装Webpack命令

npm install webpack webpack-cli -g

局部安装Webpack

npm install Webpack Webpack-cli --save-dev

通常我们直接在命令行中执行Webpack命令时,执行的是当前全局安装的Webpack命令;当我们想要使用安装在项目内部中的Webpack时,可以通过在package.json文件中的script脚本下定义执行Webpack命令;项目中我们推荐使用局部命令,防止项目所需依赖包版本不同而导致冲突。

script: {
  "build": "Webpack"
}

Webpack在执行构建时默认会从项目根目录下的webpack.config.js文件中读取配置,也可以通过命令行参数--config指定配置文件名;由于Webpack构建运行在Node.js环境下,所以该文件最后需要通过CommonJS规范导出一个描述如何构建的Object对象

入口( entry )

配置模块入口;指定Webpack执行构建的起点入口,来作为构建其内部依赖图的开始。可以是单入口或多入口:

用法 entry: String|Array|Object<String|Array>

/*
* String 单入口、单出口
* 这是最简单也最常用的入口起点配置方式,Webpack从该主入口文件递归构建依赖图,最终打包生成一个chunk输出
*/
module.exports = {
  entry: "./main.js"
}

//Array 多入口,但是打包后也是生成单个出口文件
module.exports = {
  entry: ["./main1.js","./main2.js"]
}

/*
* Object 多入口,每个入口生成一个Chunk
* 对象写法的可配置性最强,
*/

module.exports = {
  entry:{
    main1: "./main1.js",
    main2: "./main2.js"
  }
}

出口( output )

配置如何输出最终想要的代码,output是一个Object,里面包含一系列配置项;下面分别介绍它们:

path: 指明存放文件的目录地址, 必须是绝对路径,默认为/dist

filename: 打包生成的文件名, 可以配合entry使用占位符

占位符名称含义
id模块的唯一标识,从0开始
name模块名称
hash本次构建的hash
chunkhashchunk内容的hash

[hash]和[chunhash]的长度是可以指定的,[hash:8]代表取8位hash值,默认20位

publicPath: 配置线上资源的URL前缀, 当我们把打包生成后的资源文件托管到CDN上时,就需要该配置项; 在前期写配置文件时我们可能还不知道输出文件的publicPath, 可以先留空,后期可以直接在入口文件中通过使用自由变量 __webpack_public_path__来设置

module.exports = {
  output:{
   	path:path.resolve(__dirname, './dist'),
  	filename: 'bundle.js'
  }
}

crossOriginLoading: Webpack输出的部分代码块可能需要异步加载,而异步加载是通过JSONP方式实现的,JSONP的原理是动态的向HTML中插入一个标签,通过src去加载跨域资源;而这个crossOriginLoading就是用来设置这个值:

  • false: 禁止跨域加载(默认)
  • anonymous : 在加载此脚本资源时不会带上用户的Cookies
  • use-credentials: 在加载此脚本资源时带上用户的Cookies

模块( module )

配置处理模块规则;Webpack默认只能处理jsjson文件,module选项决定如何处理这些其他类型的文件

rules: 配置模块的读取和解析规则,通常用于配置loader。对于其他类型的文件需要使用各种loader将其转化为Webpack能够处理的文件,然后再构建打包输出。这可以使我们打包除JavaScript之外的任何资源;常用loader

file-loader

对文件不做任何处理,直接输出到指定文件夹,并返回相对URL, 输出的文件名可配置

module: {
	rules: [
    {
      test: /\.(png|jpg|jpeg)$/,
      use: {
        loader: 'file-loader',
        options: {
          name: [name]-[hash].[ext] ,
          outputPath: 'imgs',
          publicPath: 'assests/'
        }
      }
    }
  ]
}

/** placeholders 占位符
*	name:资源文件原名称 
*	hash:根据文件内容生成的哈希值  
* ext:资源文件扩展名
*/

url-loader

功能类似于file-loader,但是在文件大小低于指定限制时,可以返回base64DataURL;大于制定限制时,功能同file-loader一样,不做任何处理直接输出到目标文件夹内。

module: {
	rules: [
    {
      test: /\.(png|jpg|jpeg)$/,
      use: {
        loader: 'url-loader',
        options: {
          limit: '1024'
        }
      }
    }
  ]
}

/** placeholders 占位符
*	name:资源文件原名称 
*	hash:根据文件内容生成的哈希值  
* ext:资源文件扩展名
*/

css相关loader

less-loader: 将less转换为css
css-loader: 将css转换为CommomJs模块
style-loader: 创建style标签,将css添加到页面中

noParse:可以让Webpack忽略跳过那些没采用模块化的文件,从而提高构建性能。

解析( resolve )

配置寻找模块规则,设置模块如何被解析;Webpack在启动后会从配置的入口模块出发找出所有依赖的模块,resolve配置Webpack如何寻找模块所对应的文件。

alias

给常用路径配置别名,可以减少模块路径解析时间,也方便文件在不同地方引用

module.exports = {
	resolve: {
		alias: {
      "react": '/node_modules/react/react.min.js'
    }
	}
}

extensions:在导入语句没带文件后缀时,Webpack会自动带上后缀去尝试访问文件是否存在,默认['.js', '.json']

modules:配置Webpack去那些目录下寻找第三方模块,默认node_modules文件夹

devtool

控制是否生成,以及如何生成source map;不同格式的source map值回明显影响到构建和重构建的速度

那么何为source map? 通常我们用于部署到生产环境的代码,一般是经过压缩后的(删除了注释、空格、换行等不必要的字符串)来减小代码体积。当代码出错调试时,我们就无法在控制台快速定位到问题位置,这就是source map想要解决的问题。

plugins

用于扩展Webpack的功能,可以让Webpack做任何与构建有关的事情,Plugin的配置也很简单,Plugins 配置项接收一个数组,数组里的每一项都是一个要使用new关键字生成的Plugin的实例, Plugin`需要的参数都是通过构造函数传入。常用的一些插件:

html-webpack-plugin

clean-webpack-plugin

DevServer

DevServer会启动一个http服务器用于服务网页请求,同时会帮助启动Webpack,并接收Webpack发出的文件变更信号,通过WebSocket协议自动刷新网页做到实时预览。

host: 指定要使用的host

port:指定监听的端口

proxy:配置服务代理

hot:启用模块热替换功能,DevServer的默认行为是在发现源代码被更新后通过自动刷新整个页面来做到实时预览,开启热模块替换功能后,将在不刷新整个页面的情况下,通过用新模块替换老模块来做到实时预览

contentBasedevServer.contentBase配置DevServer服务器的文件根目录,默认情况下为当前的执行目录(即配置文件所在目录)

open:服务启动后,自动打开默认浏览器

compress:为每个静态文件开启gzip,为boolean类型,默认值为false