深入理解Webpack 中路径的配置

前言

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 采用默认值。

总结

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

好了,以上就是这文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • webpack配置文件和常用配置项介绍

    1.安装webpack 1.全局安装webpack:npm install webpack -g 或者转化了cnpm则将npm改为cnpm进行安装 2.进行初始化建立package.json文件记录插件,命令行:npm init 3.webpack安装到项目并将写入package.json的devDependencies中, 命令行:npm install webpack --save-dev. 2.webpack配置文件介绍 1.webpack需要配置文件webpack.config.js,手

  • webpack常用配置项配置文件介绍

    一.webpack基础 1.在项目中生成package.json:在项目根目录中输入npm init,根据提示输入相应信息.(也可以不生成package.json文件,但是package.json是很有用的,所有建议生成) 2.安装webpaack a.在全局中安装webpack:npm install webpack -g b.将webpack安装到项目并将webpack写入package.json的devDependencies中:进入项目根目录,然后在命令行中输入npm install w

  • 基于webpack 实用配置方法总结

    1.webpack.config.js配置文件为: //处理共用.通用的js var webpack = require('webpack'); //处理html模板 var htmlWebpackPlugin = require('html-webpack-plugin'); //css单独打包 var ExtractTextPlugin = require("extract-text-webpack-plugin"); // 获取html-webpack-plugin参数的方法 v

  • webpack配置的最佳实践分享

    本文主要介绍了关于webpack配置的最佳实践,本文分享的实践具有以下的优势: 使用happypack提升打包速度. 使用MD5 hash可以生成文件版本,进行版本控制 在非单页面的系统中支持多个入口的配置 模板中可以利用htmlplugin输出一些配置性的信息 支持devserver,支持本地json数据的mock 一.webpack最佳实践中的需求 1.热加载 2.语法校验 3.js打包 4.模板打包 二.解决方案 1.webpack.config.json var path = requi

  • 深入理解Webpack 中路径的配置

    前言 Webpack2 中有很多涉及路径参数配置,若不知其所以然,很容易混淆出错.本文尽可能的汇集了 Webpack2 中涉及路径的配置,力争深入浅出. context context 是 webpack 编译时的基础目录,入口起点(entry)会相对于此目录查找. 默认值为当前目录,webpack设置 context 默认值代码 可以本地下载: this.set("context", process.cwd()); process.cwd()即webpack运行所在的目录(等同pac

  • webpack中的代理配置详解

    目录 作用: 使用场景一: 使用场景二 使用场景三 使用场景四: 使用场景五: 解决跨域原理 vue-cli中proxyTable配置接口地址代理示例 更多参数 作用: 1.解决开发环境跨域问题(不用再去配置nginx和host) 2.如果你有单独的后端开发服务器API,并希望在同域名下发送API请求,那么代理某些URL会很有用 下面介绍一下五种经常使用的场景 使用场景一: 请求到 /api/xxx 现在会被代理到请求 http://localhost:3000/api/xxx, 例如 /api

  • 深入理解webpack process.env.NODE_ENV配置

    在node中,有全局变量process表示的是当前的node进程.process.env包含着关于系统环境的信息.但是process.env中并不存在NODE_ENV这个东西.NODE_ENV是用户一个自定义的变量,在webpack中它的用途是判断生产环境或开发环境的依据的. 为了查看 process的基本信息,我们可以在文件夹中 新建一个 process.js 文件,在里面加一句代码:console.log(process);然后进入该文件夹,执行 node process.js 可以在命令行

  • react项目中@路径简单配置指南

    目录 前言 1. 安装craco 2.根路径下创建 craco.config.js 3. 修改package.json文件的script字段 4.使用 补充:React 配置 @ 路径别名 总结 前言 无论是vue还是react开发,我们通常需要引入路径的便捷化配置,通常我们都会约定使用路径@作为根路径地址.如果是个人react开发的@路径简单配置 1. 安装craco yarn add @craco/craco 2.根路径下创建 craco.config.js const path = req

  • Webpack中Source Map配置深入解析

    目录 为什么需要Source Map devtool选项 devtool为false和'eval'有啥区别 准备工作 1,创建项目 安装依赖 2,添加文件 3,写配置 webpack.config.js 4,在package.json中添加 5,执行 npm run build,打包文件生成到了dist文件夹中,至此,准备工作完毕. 观察devtool为false时 1, 在dist/main.js中 2,在浏览器中,观察开发者工具中的Sources. 小结 观察devtool为'eval'时

  • Webpack中使用环境变量的各种正确姿势

    目录 写在前边 业务代码使用环境变量 使用webpack.DefinePlugin插件在业务代码中注入环境变量 webpack.DefinePlugin引发的思考 definePlugin所谓的"环境变量"实现方式 JSON.stringify()处理环境变量 构建过程中使用环境变量 传统环境变量方法使用webpack构建过程环境变量. 总结 写在前边 你还在为Webpack中各种打包配置而烦恼吗? 今天我们来聊聊webpack中注入环境变量的各种姿势,或者你会觉得注入环境变量通过命令

  • 详解vue-cil和webpack中本地静态图片的路径问题解决方案

    本文介绍了vue-cil和webpack中本地静态图片的路径问题解决方案,分享给大家,具体如下: 1 本地图片动态绑定img的src属性 一般我们在html中或者vue组件文件中引用图片是这样,这是不需要做特别处理的 我们将图片放入assets中或者重新建立个文件夹img什么的都可以,随意- 但是我们这时候可能会有个需求就是我们要动态绑定一组本地图片 1 将图片当成模块先引进来,再绑定 但是这种做法局限性比较大,模块化差,代码不好看 . 如果我做的是纯静态的网站展示,有许多的本地静态资源需要加载

  • Webpack中publicPath路径问题详解

    最近自己在搭建一个基于webpack的react项目,遇到关于output.publicPath和webpack-dev-server中publicPath的问题,而官方文档对它们的描述也不是很清楚,所以自己研究了下并写下本文记录. output output选项指定webpack输出的位置,其中比较重要的也是经常用到的有 path 和 publicPath output.path 默认值: process.cwd() output.path 只是指示输出的目录,对应一个 绝对路径 ,例如在项目

  • IIS8.5 配置错误提示不能在此路径中使用此配置节的解决办法

    今天刚安装好IIS8.5, 我的系统是win8.1 enterprise版本. 建了一个简单的页面准备调试,却发现了这个错误: 详细错误信息模块 IIS Web Core 通知 BeginRequest 处理程序 尚未确定 错误代码 0x80070021 配置错误 不能在此路径中使用此配置节.如果在父级别上锁定了该节,便会出现这种情况.锁定是默认设置的(overrideModeDefault="Deny"),或者是通过包含 overrideMode="Deny"或旧

  • Webpack中SplitChunksPlugin 配置参数详解

    代码分割本身和 webpack 没有什么关系,但是由于使用 webpack 可以非常轻松地实现代码分割,所以提到代码分割首先就会想到使用 webopack 实现. 在 webpack 中是使用 SplitChunksPlugin 来实现的,由于 SplitChunksPlugin 配置参数众多,接下来就来梳理一下这些配置参数. 官网上的默认配置参数如下: module.exports = { //... optimization: { splitChunks: { chunks: 'async'

随机推荐