Webpack2 中有很多涉及路径参数配置,若不知其所以然,很容易混淆出错。本文尽可能的汇集了 Webpack2 中设计路径的配置,力争深入浅出。

context

context 是 webpack 编译时的基础目录,入口起点(entry)会相对于此目录查找。

若不配置,默认值为当前目录,webpack设置 context 默认值代码

this.set("context", process.cwd());

process.cwd()即webpack运行所在的目录(等同package.json所在目录)。

context 应该配置为绝对路径,假如入口起点为src/main.js,则可以配置:

{
context: path.resolve('./src'),
entry: './main.js'
}

此时 entry 不能再配置为'./src/main.js',因为 webpack 会相对于 context 配置的 src 目录区查找入口起点(main.js),而 main.js 就在此目录下,所以应当将 entry 配置为当前目录(./)。

context 有什么实际作用?官方文档的解释是使得你的配置独立于工程目录 「This makes your configuration independent from CWD (current working directory)」。怎么理解?举个例子,在分离开发生产配置文件时候,一般把 webpack.config 放到 build 文件夹下,此时 entry 却不用考虑相对于 build 目录来配置,仍然要相对于 context 来配置,这也就是所谓的独立于工程目录。

需要注意的是,output 的配置项和 context 没有关系,但是有些插件的配置项和 context 有关,后面会说明。

output

output.path

打包文件输出的目录,建议配置为绝对路径(相对路径不会报错),默认值和 context 的默认值一样,都是process.cwd()。

除了常规的配置方式,还可以在 path 中用使用 [hash] 模板,比如配置:

output: {
path: path.resolve('./dist/[hash:8]/'),
filename: '[name].js'
}

打包后的目录如下:

这里的 hash 值是编译过程的 hash,如果被打包进来的内容改变了,那么 hash 值也会发生改变。这个可以用于版本回滚。你也可以配置为path.resolve(`./dist/${Date.now()}/`)方便做持续集成等。

ouput.publicPath

记得最开始学习 Webpack 的时候,一直没把 publiPath 理解透彻,甚至还错误的认为它和 output.path 有关联。这个配置项在很多场景是非常重要的,如果不深入理解,就不能灵活运用。

怎么快速又准确的理解 publicPath,我觉得可以用下面的这个公式来表述:

静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径

举例说明:

output.publicPath = '/static/'

// 图片 url-loader 配置
{
name: 'img/[name].[ext]'
}
// 那么图片最终的访问路径为
output.publicPath + 'img/[name].[ext]' = '/static/img/[name].[ext]' // JS output.filename 配置
{
filename: 'js/[name].js'
}
// 那么JS最终访问路径为
output.publicPath + 'js/[name].js' = '/static/js/[name].js' // CSS
new ExtractTextPlugin("css/style.css")
// 那么最终CSS的访问路径为
output.publicPath + 'css/style.css' = '/static/css/style.css'

publicPath 默认值为空字符串,接下来看其他各种常见的 publicPath 配置的实际意义。

publicPath 设为相对路径,相对路径实际上是相对于index.html的路径,为什么这么说?比如publicPath:"./dist/",JS文件名为bundle.js,按上面的公式,最终访问JS的路径为./dist/bundle.js, 这个路径同时也是index.html引用bundle.js的路径,既然要在index.html通过相对路径引用bundle.js,那么index.html的位置就决定了 publicPath 的配置,比如index.html在A文件夹下,而发布的路径不想放到A文件夹里,而是想和A文件夹同级,那么就应配置为publicPath :"../dist/",这就是相对于index.html的路径来讲,bundle.js在上一层的dist文件夹里。相对路径的好处是本地可以访问,比如一些混合 APP 用的file协议,用绝对路径肯定是不行的。

publicPath 设为相对于协议url(//)或http地址(http://),比如publicPath:'http://wwww.qinshenxue.com/static/',开发环境当然是不能这么干,使用这个的场景是将资源托管到CDN,比如公司的静态资源服务器等。

另外publicPath应该以'/'结尾,同时其他loader或插件的配置不要以'/'开头。

webpack-dev-server

publicPath

上面讲过 webpack 的 publicPath,那么这里的 publicPath 和 上面的publicPath是不是一回事呢?答案是两者区别很大,首先这里的publicPath用于开发环境的,因此不会出现配置 http 地址的情况,那这两者到底有啥区别呢?

我们知道 webpack-dev-server 打包的内容是放在内存中,通过express匹配请求路径,然后读取对应的资源输出。这些资源对外的根目录就是publicPath,可以理解为和 outpu.path 的功能一样,将所有资源放在此目录下,在浏览器可以直接访问此目录下的资源。

但是这个路径仅仅只是为了提供浏览器访问打包资源的功能,webpack中的loader和插件仍然是取ouput.publicPath,比如CSS里面的图片最终的路径仍是"/static/img/xxxx.png",这也是为什么官方推荐 publicPath 和 webpack 配置的保持一致(除了http地址),配置一致才能正常访问其他静态资源。

上面的解释可能还是比较生硬,还是举几个例子来说明:

本例将两处 publicPath 配置成不一样的,这样更容易对比理解。

// webpack.config.js
output: {
path: path.resolve(`./dist/`),
filename: 'js/[name].js',
publicPath: '/static/'
}
// api 调用 webpack-dev-server
var webpack = require('webpack');
var webpackDevServer = require('webpack-dev-server');
var config = require("./webpack.config");
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
hot: true,
publicPath: '/web/'
});
server.listen(8282, "0.0.0.0")

如何查看 webpack-dev-server 所有启动后的资源访问路径呢?有个简单的方法,就是访问/webpack-dev-server,本例访问截图如下:

上面的资源可以点击查看,你会发现,资源的路径都是/web/*****,所以在index.html中引入JS的路径应为/web/js/main.js,同时也能看到,style.css中的图片路径仍然为/static/img/****.png,而不是/web/。

html-webpack-plugin

这个插件的几处配置受路径配置影响,因此需要专门说明下。

template

template的路径是相对于 output.context,源码如下:

this.options.template = this.getFullTemplatePath(this.options.template, compiler.context);

因此 template 对应的文件需要放在 ouput.context 配置的目录下才能被识别。

filename

filename的路径是相对于 output.path,源码如下:

this.options.filename = path.relative(compiler.options.output.path, filename);

在 webpack-dev-server 中,则相对于 webpack-dev-server 配置的 publicPath。

若 webpack-dev-server 中的 publicPath 和 ouput.publicPath 不一致,在这种配置下使用html-webpack-plugin是有如下问题:

  • 自动引用的路径仍然以 ouput.publicPath 为准,和 webpack-dev-server 提供的资源访问路径不一致,从而不能正常访问;
  • 浏览 index.html 需要加上 webpack-dev-server 配置的 publicPath 才能访问(http://localhost:8282/web/)。

这两个问题也反推出了最方便的配置为:

  • ouput.publicPath 和 webpack-dev-server 的publicPath 均配置为'/',vue-cli 就是这种配置
  • template 放在根目录,html-webpack-plugin 不用修改参数的路径,filename 采用默认值。

总结

目前就针对上面基础路径做了简单的解释说明,如有错误,请不吝指出,后续若发现其他相关路径配置,再作补充。

详解Webpack2的那些路径的更多相关文章

  1. Spring配置文件详解 – applicationContext.xml文件路径

    Spring配置文件详解 – applicationContext.xml文件路径 Java编程                 spring的配置文件applicationContext.xml的默 ...

  2. Spring配置文件详解 - applicationContext.xml文件路径

    spring的配置文件applicationContext.xml的默认地址在WEB-INF下,只要在web.xml中加入代码 org.springframework.web.context.Cont ...

  3. L009文件属性知识详解小节

    本堂课分为5部分内容 1.linux下重要目录详解 2.PATH变量路径内容 3.linux系统中文件类型介绍 4.linux系统中文件属性详细介绍 5.linux系统文件属性inode与block知 ...

  4. Android核心分析之十五Android输入系统之输入路径详解

       Android用户事件输入路径 1 输入路径的一般原理 按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题.按键,鼠标等用户消息 ...

  5. iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)

    前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...

  6. Linux crontab 命令详解(含配置文件路径)

    编辑/etc/crontab 文件配置cron cron 服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用cron服 ...

  7. [自制操作系统] JOS文件系统详解&支持工作路径&MSH

    本文分为两部分: 第一部分将详细分析JOS的文件系统及文件描述符的实现方法. 第二部分将实现工作路径,提供新的系统调用,完善用户空间工具. 本文中支持的新特性: 支持进程工作目录 提供getcwd与c ...

  8. php中相对路径和绝对路径如何使用(详解)

    目录 一.总结 一句话总结: 1.php中用用“/”表示根目录么? 2.什么符号表示当前目录(asp,jsp,php都一样)? 3.php中如何使用$_SERVER['DOCUMENT_ROOT']做 ...

  9. 详解如何在RVIZ中用Marker显示机器人运动路径

    写在前面 最近有道作业题需要将机器人的历史路径显示出来,但是网上很多相关的教程都是搬运了官网的链接,并没有详细的操作流程...因此我又花费了很多时间去ros官网上学习marker的用法,学习怎么写pu ...

随机推荐

  1. ios开发学习笔记003-流程控制和类型转换

    流程控制 顺序结构.选择结构.循环结构 1.顺序结构 程序默认是顺序执行的. 2.选择结构 if选择语句 第一种情况 if(条件)//条件成立执行下面语句 { //语句 } 第二种情况 if(条件)/ ...

  2. C# 调试之 Debug.WriteLine()、Trace.WriteLine()

    Trace 类 和 Debug 类的区别在于,Trace 类会同时在 Debug.Release 模式下起作用,而 Debug 只作用在 Debug 模式下. 区别: 1. 输出跟踪信息 Trace. ...

  3. Leetcode 648.单词替换

    单词替换 在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词(successor).例如,词根an,跟随着单词 other(其他),可 ...

  4. [oldboy-django][2深入django]rest-framework教程

    # rest-framework教程 - settings.py INSTALL-APPS = [ 'snippets', # app 'rest-framework', ] - 创建model # ...

  5. [oldboy-django][1初识django]阻止默认事件发生 + ajax + 模态编辑对话框

    阻止默认事件发生 a 阻止a标签默认事件发生方法 <a href="http://www.baidu.com" onclick="modalEdit();" ...

  6. [已解决]Argument list too long如何处理?

    Argument list too long 本质是需要处理的长度超过系统的长度,因此无法执行相关命令. 经过搜索发现了两种方法,思想都是将参数切分成小的段落进行执行. 法一:通过xargs传递参数 ...

  7. POJ 3494 Largest Submatrix of All 1’s 单调队列||单调栈

    POJ 3494 Largest Submatrix of All 1’s Description Given a m-by-n (0,1)-matrix, of all its submatrice ...

  8. Hive 01 概述、安装配置

    概述 数据仓库:是一个面向主题的.集成的.不可更新的.随时间不变化的数据集合,它用于支持企业或组织的决策分析处理. 数据仓库的结构和建立过程: 数据源 数据存储及管理 ETL Extract 提取 T ...

  9. php读写文件要加锁

    http://www.bubuko.com/infodetail-241753.html

  10. JavaScript (JS)基础:BOM 浅析 (含window对象相关基本方法、属性解析)

    ① window对象(Math方法也属于window对象): window对象是JavaScript中的顶级对象,所有定义在全局作用域中的变量.函数都会变成window对象的属性和方法,window对 ...