Webpack实战(三):作为前端你不得不懂的Webpack资源入口和出口的配置
关于Webpack前两篇跟大家分享的主要是Webpack的一些基本的配置,今天开始我们详细了解一下有关Webpack的各种配置,今天主要跟大家分享的是Webpack的资源入口和资源出口的配置。
如果想了解前两篇的文章请访问下面的地址:
Webpack实战(一):Webpack打包工具安装及参数配置
Webpack实战(二):webpack-dev-server的介绍与用法
资源入口配置
资源入口配置是Webpack配置中不可缺少的一个环节,Webpack通过context和entry这两个配置项来共同决定入口文件的路径。从英文翻译过来的字面的意思可以了解到context是上下文的意思,entry是入口,在配置入口的时候其实做了两件事情:
- 确定入口模块位置,告诉Webpack从哪里开始进行打包。
- 定义chunk name。如果工程只有一个入口,那么默认其chunk name为“main”;如果工程有多个入口,我们需要为每个入口定义chunk name,来作为该chunk的唯一标识。
context可以理解为资源入口的路径前缀,在配置时要求必须使用绝对路径的形式,配置代码例子如下:
const path = require('path')
module.exports = {context: path.join(__dirname, './src')entry: './index.js',output: {path: path.join(__dirname, 'dist'),filename: 'bundle.js'},mode: 'development',"devServer": {"publicPath": './dist',"port": 3000 }
}
其实context 的配置相当于引入前缀‘src’,如果不用context,可以配置成
entry: './src/index.js'
context这个配置可以省略,配置context的主要目的是让entry的编写更加简洁,尤其是在多入口的情况下。
entry的配置可以有多种形式:字符串、数组、对象、函数。可以根据不同的需求场景来选择。
- 字符串类型入口
直接传入路径入口,如下
module.exports = {entry: './src/index.js',output: {filename: 'bundle.js'},mode: 'development',"devServer": {"publicPath": './dist',"port": 3000 }
}
- 数组类型入口
传入一个数组的作用是将多个资源预先合并,在打包时Webpack会将数组中的最后一个元素作为实际的入口路径。如:
module.exports = {entry: ['./add.js', './index.js'],output: {filename: 'bundle.js'}
}
其实这种做法相当于字符串引入的一种,就如
module.exports = {entry: './src/index.js',output: {filename: 'bundle.js'}
}
// index.js 文件引入add文件
import './add'
数组类型入口其实数组里的js文件最后还是合并到一个文件bundle.js上
- 对象类型入口
如果想要定义多入口,则必须使用对象的形式。对象的属性名(key)是chunk name,属性值(value)是入口路径。如
module.exports = {entry: {index: './src/index.js', // chunk name 为 indexadd: './src/add.js' // chunk name 为 add
},output: {filename: 'bundle.js'}
}
注意:对象的属性值也可以为字符串或数组。
module.exports = {entry: {index: ['./add2.js', './index.js'] // chunk name 为 indexadd: './src/add.js' // chunk name 为 add
},output: {filename: 'bundle.js'}
}
- 函数类型入口
用函数定义入口时,只要返回上面介绍的任何配置形式即可,如:
// 返回字符串形式的入口
module.exports = {entry: () => './src/index.js',output: {filename: 'bundle.js'}
}// 返回对象形式的入口
module.exports = {entry: () => ({index: ['./add2.js', './index.js'] // chunk name 为 indexadd: './src/add.js' // chunk name 为 add}),output: {filename: 'bundle.js'}
}
用函数作为一个入口的好处是我们可以在函数体里添加一些动态的逻辑来获取项目的入口,另外,函数也支持返回一个Promise对象来进行异步操作。例子如下:
module.exports = {entry: () => new Promise((resolve) => {// 模拟异步操作setTimeout(()=> {resolve('./src/index.js')}, 1000)}),output: {filename: 'bundle.js'}
}
资源出口配置
接下来,让我们详细去了解一下资源出口的配置,资源出口配置的参数大部分都在output里面,这里先了解一下几个常用的配置参数。
- filename
filename是控制输出资源的文件名,是字符串形式
如:
const path = require('path')
module.exports = {context: path.join(__dirname, './src'),entry: './index.js',output: {path: path.join(__dirname, 'dist'),filename: 'bundle.js'},mode: 'development',"devServer": {"publicPath": './dist',"port": 3000 }
}
打包效果如下
filename不仅可以是文件名,也可以是路径,如下:
const path = require('path')
module.exports = {context: path.join(__dirname, './src'),entry: './index.js',output: {filename: './dist/bundle.js'},mode: 'development'
}
在多入口的场景中,如果需要为对应产生的每个bundle指定不同的名字,Webpack支持使用一种类似模板语言的形式动态地生成文件名,如:
const path = require('path')
module.exports = {context: path.join(__dirname, './src'),entry: {index: './index.js', //chunk name 为indexindex2: './index2.js' //chunk name 为index2},output: {filename: '[name].js'},mode: 'development'
}
在资源输出时,上面配置的filename中的[name]会被替换为chunk name,因此最后项目中实际生成的资源是index.js与index2.js
在我们做实际项目中,使用比较多的是[name],它与chunk是一一对应的关系,并且可读性较高。如果要控制客户端缓存,最好还要加上[chunkhash],因为每个chunk所产生的[chunkhash]只与自身内容有关,单个chunk内容的改变不会影响其他资源,可以最精确地让客户端缓存得到更新。
如下:
const path = require('path')
module.exports = {context: path.join(__dirname, './src'),entry: {index: './index.js',index2: './index2.js'},output: {filename: '[name]@[chunkhash].js'},mode: 'development'
}
打包的效果如下:
这个[chunkhash] 更新缓存配置一般只在生产环境中配置,不在开发环境中配置
- path参数
path可以指定资源输出的位置,要求值必须为绝对路径。如:
const path = require('path')
module.exports = {context: path.join(__dirname, './src'),entry: {index: './index.js',index2: './index2.js'},output: {path: path.join(__dirname, 'dist')filename: '[name]@[chunkhash].js'},mode: 'development'
}
在Webpack 4之后,output.path已经默认为dist目录,除非我们需要更改它,否则不必单独配置。
- publicPath
module.exports = {entry: './src/index.js',output: {filename: 'bundle.js'},mode: 'development',"devServer": {"publicPath": './dist',"port": 3000 }
}
publicPath跟path有很大的区别:path用来指定资源的输出位置,而publicPath则用来指定资源的请求位置的。
- 输出位置:打包完成后资源产生的目录,一般将其指定为项目中的dist目录。
- 请求位置:由JS或CSS所请求的间接资源路径。页面中的资源分为两种,一种是由HTML页面直接请求的,比如通过script标签加载的JS;另一种是由JS或CSS请求的,如异步加载的JS、从CSS请求的图片字体等。publicPath的作用就是指定这部分间接资源的请求位置。
webpack-dev-server的配置中也有一个publicPath,但是,这个publicPath与Webpack中的配置项含义不同,它的作用是指定webpack-dev-server的静态资源服务路径。详情请查看《Webpack实战(二):webpack-dev-server的介绍与用法》
为了避免开发环境和生产环境产生不一致而造成开发者的疑惑,我们可以将webpack-dev-server的publicPath与Webpack中的output.path保持一致,这样在任何环境下资源输出的目录都是相同的
总结
有关Webpack资源入口和资源出口的配置就暂时分析到这里,这仅代表个人观点,欢迎拍砖,如想了解更多请扫描下面:
Webpack实战(三):作为前端你不得不懂的Webpack资源入口和出口的配置相关推荐
- Webpack实战(五):轻松读懂Webpack如何分离样式文件
在上一篇文章中我给大家分享了预处理器(loader),里面讲到了style-loader 和css-loader,有关样式引入的问题,但是上面的样式文件只是引入到style标签里面,并不是我想要的样式 ...
- Webpack实战(四):教教你如何轻松搞定-预处理器(loader)
前面三节,我主要给大家分享了有关webpack的一些配置的知识点,如何打包js文件,而如果我们遇到其他类型的资源如图片.css.字体font等等,我们该如何处理呢?今天会介绍预处理器(loader), ...
- Webpack实战:入门、进阶与调优(第2版)
你是否经常听到项目组的同事抱怨:"为什么Webpack这么慢?""为什么Webpack又出错了?" "发布到线上的代码为什么不能正常工作?" ...
- (23/24) webpack实战技巧:如何在webpack环境中使用Json
(23/24) webpack实战技巧:如何在webpack环境中使用Json 在webpack1或者webpack2版本中,若想在webpack环境中加载Json文件,则需要加载一个json-loa ...
- cli vue webpack 实战_Vuejs技术栈从CLI到打包上线实战全解析
前言 本文是自己vue项目实践中的一些总结,针对Vue2及相关技术栈,实践中版本为2.3.3. 开发前须知 vue-cli 在开发前,我们要至少通读一遍vue官方文档和API(看官方文档是最重要的,胜 ...
- 前端自动化构建工具之webpack入门——简单入门
写在前面 这篇博客也是参照别人的webpack入门,加上自己的一些操作,还有我在此过程中遇到的困难.如果是已经入门的或者这方面的高手,请绕行,也请勿吐槽. 正文开始 我们为什么要学习webpack 首 ...
- (17/24) webpack实战技巧:生产环境和开发环境并行设置,实现来回切换
(17/24) webpack实战技巧:生产环境和开发环境并行设置,实现来回切换 1. 概述 生产环境和开发环境所需依赖是不同: --开发依赖:就是开发中用到而发布时用不到的.在package.jso ...
- pytorch快速入门与实战——三、Unet实现
专栏目录:pytorch(图像分割UNet)快速入门与实战--零.前言 pytorch快速入门与实战--一.知识准备(要素简介) pytorch快速入门与实战--二.深度学习经典网络发展 pytorc ...
- 06.简书项目实战三:详情页面和登录功能实现
简书项目实战三:详情页面和登录功能实现 1. 详情页面布局 这部分的布局比之前的简单多了,就一个标题加上主要内容而已. export default class Detail extends Comp ...
最新文章
- 如何破解root以及grub密码
- jvm十:类加载器解析
- 给定数组 求和等于固定值 算法_别人家的面试题:不可变数组快速范围求和
- Maven教程(一)
- 选择Java加密算法第3部分–公钥/私钥非对称加密
- oracle11g中的join,sql - 使用Oracle 11g中的+符号进行左外连接
- 闭包---在函数内部再定义一个函数
- 【c++】简单的string类的几个基本函数
- Linux中文件权限查看和修改
- cmder的下载和使用
- 2021年全球与中国飞机飞行控制系统(FCS)行业市场规模现状及企业市场份额分析
- 计算机机房的维护方案,机房设备维护方案.doc
- Teamviewer远程,应用界面显示空白
- 内网服务器使用代理上网
- oracle inst 自动重启,oracle rac 节点自动重启
- Sci-Hub十周年迎来解封!科研er的福音!附可用网址!
- Mac配置item2高亮颜色
- 2023 IEEE Fellow出炉:唐立新、宗成庆、朱军、姬水旺、李佳等入选
- 运用python求次方
- 【Yolo3】入门目标检测实验--Python+Opencv2+dnn
热门文章
- java中面向对象租车问题_答答租车系统-Java面向对象的学习
- Ubuntu终极指南
- 软考信息安全工程师备考笔记3:第三章网络安全基础备考要点
- java 左侧菜单栏收缩_页面左侧可收缩菜单案例
- 问题:连接查询和子查询的区别和连接及优劣?
- 贝壳:计算绝对值(暴力破解)
- 零基础入门Python3-列表list详解
- amazeui学习笔记二(进阶开发4)--JavaScript规范Rules
- 连接mysql数据库时提示2003-can t connect to MySQL server on ip(10060)的解决办法
- AutoFac+MVC+WebApi源码----我踩过的坑