webpack 图片路径的深入浅出

涉及到的方面较广,有经验的大佬可选择性跳过。


基础

1.webpack打包本质

本质就是nodejs去执行webpack脚本,由webpack脚本对项目各个文件进行必要的编译(翻译/字符串替换)再输出到某个目录。即可以简单理解为webpack是一个nodejs的小程序,功能是读取文件内容,进行字符串修改操作后,输出内容。

因此具体的前端js文件中是不可使用nodejs的东西的,因为它们没有被nodejs运行。至于process变量,在webpack打包中时的确就是nodejs的process;在最终的浏览器中,process只是一个最简单的副本对象,拥有与nodejs的process相似的数据内容,但是并不是同一对象。

2.import from 和require

webpack相关脚本中的require和我们前端js文件中使用的require不是一回事。

你可以发现在webpack相关文件中,全部使用require导入,这个require就是nodejs模块化的关键字。

而具体前端js文件中,使用到的require是由webpack提供的一个函数,功能类似但更加强大。主要能力有:完成导入,参数可以省略部分后缀名(需要配置)、是目录时自动寻找该目录下的index.js并导入、能够使用别名(alias,需要配置)、导入图片(实际导入为base64编码后的字符串)、提供给loader以扩展导入vue和sass等更多文件
至于import from,实际上是语法糖,import img from './a.jpg'被处理为const img=require('./a.jpg'),这个require就是上述的require,是webpack提供的一个函数。

注意:对于js模块化,你可能还需要了解下CommonJS和ES6规范的语法形式:js require/exports和import/export
另外nodejs中借助babel相关包,同样可以提供import from的语法糖,但是它的这个import from只是换成nodejs的关键字require,并没有像webpack那样处理(实际上也不需要)。我这里只是想提醒下这个差异,毕竟前端使用nodejs开发时,并不需要nodejs跑我们的前端js文件,因此我们的前端文件拥有更多可能的自定义语法、格式、功能


正文

1.webpack模块化处理解析配置

即webpack的resolve配置:解析(resolve)

  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src'),//此resolve是外面定义的一个函数,用于生成绝对路径
      '@assets': resolve('src/assets')
    }
  },

上面require提到的别名、可省略扩展名在这里配置。
至于require函数中的路径参数,具体的解析法则如下:webpack 如何解析代码模块路径

1.解析相对路径
查找相对当前模块的路径下是否有对应文件或文件夹
是文件则直接加载
是文件夹则继续查找文件夹下的 package.json 文件
有 package.json 文件则按照文件中 main 字段的文件名来查找文件
无 package.json 或者无 main 字段则查找 index.js 文件.
2.解析模块名
查找当前文件目录下,父级目录及以上目录下的 node_modules 文件夹,看是否有对应名称的模块
3.解析绝对路径
直接查找对应路径的文件

2.图片的去向

一般受url-loader和file-loader控制。
具体可以直接去看他们文档。简单而言url-loader把小图片变为base64的字符串然后直接替换路径;file-loader把url-loader没处理的那些大图片给复制到指定位置(用户设置),同时把原来的的路径替换成publicPath+指定位置(用户设置)

这里的publicPath设置有讲究,因为相对路径中css和js的起始路径不一致。
publicPath:'./',那么在打包后浏览器环境下,css的./是指css所在路径;而js中的./是指浏览器当前地址栏的url的路径目录。因此假如/mycss/a.css中有url(./a.jpg),浏览器认为图片在/mycss/a.jpg;假如在/a/b/网址下,js设置img.src=url(./a.jpg),浏览器认为图片在/a/b/a.jpg
这个时候我们可以调整file-loader处理图片时的参数,单独为其设置publicPath而不是使用全局publicPath,这比较灵活,对应上自己打包后的图片路径即可

3.图片路径

1.css中:
问题主要是"路径别名",若要使用,路径前要加个~,即url('~@assets/a.jpg')之类的。
因为css中我们无法使用require函数,url-loader和file-loader不能确定解析方式。比如说我们有个别名@代表src目录,但是恰好我们目录下有个@文件夹,那么就产生了二义性无法确定。因此默认情况下,css中所有路径都不认别名,除非路径开头有个~,指明要额外使用模块路径解析

2.html中:
同css,新版本中好像不用加~也行,见仁见智

3.js中:
不用写~,require一定使用模块路径解析。另外由于js比起他们多了动态设置,设置图片src时,没有各种loader帮我们处理了,很可能对不上打包后的目录结构。这要求我们必须正确把地址写成最终打包后的图片相对地址,十分不利于修改和维护

正确方法是用require函数(webpack提供),这个是运行时也存在的,它能够让路径参数的解析仍然从开发目录开始计算,计算法则同上所述,因此我们放心在这里写开发时的图片路径。当然,这个require返回值也如上所述,对于图片文件返回base64编码后字符串。

注意require中路径别名问题。使用别名时,需要把别名字符串的部分直接包含在参数中。即

let number=1, p1='./', p2='@assets'

img.src=require(`./assets/img${number}.jpg`)//正确
img.src=require(`@assets/img${number}.jpg`)//正确
img.src=require(`${p1}assets/img${number}.jpg`)//正确

img.src=require(`${p2}/img${number}.jpg`)//错误

我也不知道这个是bug还是什么鬼了,有了解的大佬可以说下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351