在学习webpack的时候,配置文件中有一个publicPath属性,一直不是很明白它到底是怎么用,也查了很多资料,得到最多的说法是当打包的时候,webpack会在静态文件路径前面添加publicPath的值,当我们把资源放到CDN上的时候,把publicPath的值设为CDN的值就可以了。但是在使用webpack 进行开发的时候,得到的结果却和该说法不是很一致,经过一段时间的摸索,好像是懂了一点点,至少在简单的配置中不会报错,在这里记一下,做一个总结.

  我们在使用webpack 进行开发的时候,通常是使用webpack-dev-server 进行开发,因为它的热加载,实时更新。而在生产上版本的时候,则是使用wepback命令进行打包,生成一个js 文件。上面的publicPath的使用说法适用于生产环境。当使用webpack命令进行打包上生产时,它确实是在静态资源路径前面加上publicPath的值。 但是当我们使用webpack-dev-server 进行开发时,它却不是在静态文件的路径上加publicPath的值,相反,它指的是webpack-dev-server 在进行打包时生成的静态文件所在的位置。也就是说publicPath的使用是分环境的。

  你可能有个疑问,webpack-dev-server会进行打包吗?webpack-dev-server也会进行打包,代码只要一变动,它就会打包,只不过它打包到的地方是计算机的内存,在硬盘中看不到。再具体一点,默认情况下,webpack-dev-server 会把打包后的文件放到项目的根目录下,文件名是在output配置中的filename. 但是当有publicPath 配置的时候,就不一样了。Webpack 会把所有的文件打包到publicPath指定的目录下,就是相当于在项目根目录下创建了一个publicPath目录, 然后把打包成的文件放到了它里面,只不过我们看不到而已, 文件名还是output配置中的filename。

  现在使用webpack验证一下。不过还要分两种情况,手动创建index.html文件 和html-webpack-plugin 自动创建index.html文件。手动创建html 不常见,但是我在初学webpack的时候,确实是手动创建index.html的,也是折腾了好久。不管哪种情况,先把webpack 项目搭建起来.

  新建一个文件夹webpack-tut, 执行npm init -y, 创建package.json 文件,同时初始化为node 项目。再在里面新建 src 文件夹和webpack.config.js 配置文件。在src 里面再新建css文件夹,img文件夹,index.js。css 文件夹 有一个style.css 放置样式,在img文件夹中放置一大一小两张图片, 小的图片1kb, 大的图片5kb.  index.js 作为入口文件,npm install webpack webpack-dev-server  css-loader style-loader  url-loader file-loader --save-dev 来安装依赖. package.json中先写两个命令:

  1. "scripts": {
  2. "build": "webpack",
  3. "dev":"webpack-dev-server"
  4. },

webpack.config.js 如下

  1. const path = require('path');
  2.  
  3. module.exports = {
  4. entry: path.join(__dirname, 'src/index.js'),
  5. output: {
  6. path: path.join(__dirname, 'dist'),
  7. filename:'bundle.js'
  8. },
  9. module: {
  10. rules:[
  11. {
  12. test: /\.css$/,
  13. use: ['style-loader', 'css-loader']
  14. },
  15. {
  16. test: /\.(png|jpg)$/,
  17. loader: 'url-loader',
  18. options: {
  19. limit: 3000,
  20. name: '[name].[hash:8].[ext]'
  21. }
  22. }
  23. ]
  24. }
  25. }

  style.css 如下:

  1. .small {
  2. width: 200px;
  3. height: 200px;
  4. background: url(../img/small.jpg) no-repeat;
  5. }
  6. .big {
  7. width: 500px;
  8. height: 350px;
  9. background: url(../img/big.jpg) no-repeat;
  10. }

  index.js 如下

  1. import './css/style.css';
  2. import img from './img/big.jpg';
  3.  
  4. var imgElement = document.createElement('img');
  5. imgElement.src = img;
  6. document.body.appendChild(imgElement);

  手动创建index.html文件

  现在我们在项目根目录中新建index.html, 整个index.html 如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Webpack Tut</title>
  6. </head>
  7. <body>
  8. <div class="small"></div>
  9. <div class="big"></div>
  10. </body>
  11. </html>

  现在最重要的问题是怎么引入打包后的js 文件,根据上面的分析,我们可以知道,当启动webpack-dev-server的时候,它把打包后的文件放到根目录下,并且文件名应为 bundle.js, 所以index.html文件中引入js 应该为 src="./bundle.js"

  1. <body>
  2. <div class="small"></div>
  3. <div class="big"></div>
  4. <script src="./bundle.js"></script>
  5. </body>

  现在npm run dev 启动webpack-dev-server, 然后打开浏览器,输入localhost:8080,  可以看到三张图都显示出来了,没有问题,证明分析是正确的。

  现在执行npm run build 进行打包, 打包完成后,以访问服务器的方式打开index.html,因为,打包后的文件是要发布到服务器上的。怎么使用这种方式 ?VS code 编辑器有一个扩展叫做Live Server,安装之后,在index.html中右键,有一个 open with Live Server选项, 点击,它会使用默认的浏览器以服务器的方式打开文件。这时你发现页面空白,肯定是报错了,打开控制台,bundle.js 文件没有找到,这时想起来,bundle.js是打包到 dist 目录下,修改index.html ,引入dist 下面的js.

  1. <script src="./dist/bundle.js"></script>

  刷新浏览器,页面只有一张图片,大图并没有显示出来,这是为什么呢?打开控制台, 点击Elements 选项卡可以看到

  我们js动态插入的img图片,和class=big 的div的background, 它们都是引用的根目录下的图片,但根目录下并没有这张图片,dist 目录下面有这张图片,我们想要让它引用dist下面的图片, 这时想到webpack 进行打包的时候会把publicPath指定的路径加到静态资源路径前面, 所以在webpack的配置文件中加入publicPath

  再执行npm run build重新打包,刷新浏览器,可以看到三张图片. 再打开浏览器台,可以看到img 的路径前面加了dist

  这时我们再来看看class=big的div的样式

  我们在style.css的源代码中是url(../img/big.jpg), 而在打包之后,它却把url的路径改成了dist, 因为打包后所有的静态图片都放到了dist 目录下,没有了 img 目录。

  现在npm run dev  启动webpack-dev-server , 在浏览器中输入localhost:8080  一切正常,没有错误, 我们来分析一下,这是为什么,首先要看一下,当启动webpack-dev-server的时候,发生了什么

  整个项目运行在localhost:8080下面,也就是服务器地址是localhost:8080 , 这也是我们在浏览器中输入localhost:8080的原因。当我们在浏览器中输入服务器地址,服务器会寻找它下面的index.html文件,并返回给浏览器,因为我们的项目在webpack-tut目录下启动的,它下面有index.html,这没有问题,浏览器在接受到index.html 就开始解析,它碰到script标签就会向服务器请求js 文件,js的地址是dist/bundle.js,服务器就会在dist目录下找bundle.js.  根据我们所知道的,当有publicPath 配置时,webpack-dev-server 会把打包后的资源放到publicPath 指定的目录,也就是dist 目录下,所以服务器是在dist 目录下可以找到bundle.js,没有问题,整个项目也没有报错。分析完了,但还是向下看一下吧,有意外的收获

  接着向下看:wepback output is served from /dist/ , webpack 输出(打包后的文件)放到了/dist/ 目录下,这也证明了webpack-dev-server 进行打包时,它打包到了publicPath 指定的目录。

  然后就没有什么重要的了,hash, verison,wepback 开始进行打包,最后是time, 表示耗时799ms, webpack 完成了打包,打包后的文件列出来了,一个img,名称为big.2a9adfd0.jpg,一个js 文件 bundle.js,还列了出打包所经历的各种module, 最后显示complied successful, 直到这时浏览器可以访问了。

  现在我们知道了js, img等静态文件所在的地址和名称,可以尝试访问一下。在浏览器输入localhost:8080/dist/bundle.js, 看到bundle.js文件,输入localhost:8080/dist/ big.2a9adfd0.jpg, 看到了图片,这也证明了我们的分析是正确的。

  其实有一个办法,可以看到我们localhost服务器下的资源,也就是控制台中的source 面板。

  服务器下面有一个index.html 文件和dist 文件夹,这里也可以看到webpack-dev-server 打包生成了一个dist 文件夹。

  总结:当我们手动创建index.html, 并手动指定css 或js 静态文件路径时,保证path 和publicPath的设置一致就好了。

  自动创建index.html

  现在把index.html 删除,然后通过html-webpack-plugin 自动创建index.html, 同时把dist 目录删掉。 npm install html-webpack-plugin --save-dev, webpack.config.js 修改如下

  1. const path = require('path');
  2.  
  3. // 引入webpack 和 html-webpack-plugin插件
  4. const webpack = require('webpack');
  5. const htmlWebpackPlugin = require('html-webpack-plugin');
  6.  
  7. module.exports = {
  8. entry: path.join(__dirname, 'js/index.js'),
  9. output: {
  10. path: path.join(__dirname, 'dist'),
  11. filename:'bundle.js',
  12. publicPath: '/dist/'
  13. },
  14. module: {
  15. rules:[
  16. {
  17. test: /\.css$/,
  18. use: ['style-loader', 'css-loader']
  19. },
  20. {
  21. test: /\.(png|jpg)$/,
  22. loader: 'url-loader',
  23. options: {
  24. limit: 10000,
  25. name: '[name].[hash:8].[ext]'
  26. }
  27. }
  28. ]
  29. },
  30. plugins: [
  31. new htmlWebpackPlugin() // 使用插件
  32. ]
  33. }

   npm run dev 启动服务器,浏览器,输入localhost:8080,可以看到服务器下面,都没有index.html 这个文件

  这是怎么一回事?看一下我们的配置文件,配置了publicPath,当有publicPath的时候,webpack-dev-server 会把所有打包好的文件都放到publicPath 指定的目录下,也就是dist目录,因为index.html文件是由webpack 打包生成的,所以它也在dist 目录下,那么我们应该访问服务器下面的dist 目录,所以浏览器中应该输入localhost:8080/dist/, 

  访问成功了。再看一下控制台中的source 面板,

  可以看到localhost 本地服务器下面只有一个dist 目录,dist 目录有打包好的静态资源,这也充分证明了,webpack-dev-server 会把所有的文件打包到publicPath指定的目录。这样访问有点不太方便了,最简单的办法,就是把publicPath配置去掉,这样webpack-dev-server就会把文件打包到根目录下,localhost:8080就会访问到。去掉之后重启服务器。

  没有问题。那么npm run build 打包到生产环境有没有问题呢?打包成功之后,可以发现没有问题。这是因为html和其它静态资源是在同一个文件下, html文件直接访问其它文件是不用加什么前缀路径

  总结一下,在使用html-webpack-plugin 生成index.html时,publicPath是可以不用配置的。

webpack 配置 publicPath的理解的更多相关文章

  1. 对vue中 默认的 config/index.js:配置的详细理解 -【以及webpack配置的理解】-config配置的目的都是为了服务webpack的配置,给不同的编译条件提供配置

    当我们需要和后台分离部署的时候,必须配置config/index.js: 用vue-cli 自动构建的目录里面  (环境变量及其基本变量的配置) var path = require('path') ...

  2. webpack的基本配置和一些理解

    最近花了两周的休息时间学习了webpack,能够可以编写自己项目所需要的配置文件,总体来说webpack是一种非常优秀的前端模块化的打包工具,非常值得花时间来研究学习. 什么是webpack,它的出现 ...

  3. vue-cli中webpack配置详解

    vue-cli是构建vue单页应用的脚手架,命令行输入vue init <template-name> <project-name>从而自动生成的项目模板,比较常用的模板有we ...

  4. 使用webpack配置react并添加到flask应用

    学习react,配置是很痛苦的一关,虽然现在有了create-react-app这样方便的工具,但是必须要自己配置一遍,才能更好地进行项目开发. 首先要明确一个概念:react的文件必须经过编译才能被 ...

  5. vue中config/index.js:配置的详细理解

    当我们需要和后台分离部署的时候,必须配置config/index.js: 用vue-cli 自动构建的目录里面  (环境变量及其基本变量的配置) var path = require('path') ...

  6. Webpack配置示例和详细说明

    /* * 请使用最新版本nodejs * 默认配置,是按生产环境的要求设置,也就是使用 webpack -p 命令就可以生成正式上线版本. * 也可以使用 webpack -d -w 命令,生成用于开 ...

  7. vue-cli#2.0 webpack 配置分析

    目录结构: ├── README.md ├── build │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-s ...

  8. 前端工程化(二)---webpack配置

    导航 前端工程化(一)---工程基础目录搭建 前端工程化(二)---webpack配置 前端工程化(三)---Vue的开发模式 前端工程化(四)---helloWord 继续上一遍的配置,本节主要记录 ...

  9. vue-cli webpack配置 简单分析

    vue-cli webpack配置分析 入口 从package.json可以看到开发和生产环境的入口. "scripts": { "dev": "no ...

随机推荐

  1. Centos7 安装配置mysql5.6

    Centos7下完美安装并配置mysql5.6   Centos7将默认数据库mysql替换成了Mariadb,对于我们这些还想用mysql的人来说并不是一个好消息. 最近我搜罗了网上各种安装教程,各 ...

  2. Feature Extractor[SENet]

    0.背景 这个模型是<Deep Learning高质量>群里的牛津大神Weidi Xie在介绍他们的VGG face2时候,看到对应的论文<VGGFace2: A dataset f ...

  3. Unity热更新学习(二) —— ToLua c#与lua的相互调用

    tolua 下载地址:http://www.ulua.org/index.html c#调用lua的方法,tolua的官方例子提供了很多种.我初步学了一种在做项目使用的方法.通过DoFile方法执行l ...

  4. 【原创】惊!史上最全的select加锁分析(Mysql)

    引言 大家在面试中有没遇到面试官问你下面六句Sql的区别呢 select * from table where id = ? select * from table where id < ? s ...

  5. C#(.NET) HMAC SHA256实现

    HMAC SHA256的实现比较简单,可以用多种语言实现,下面我用C#语言实现,一种结果是居于BASE64,另外一种是居于64位. C# HMAC SHA256 (Base64) using Syst ...

  6. 深入理解Redis复制

    复制 A few things to understand ASAP about Redis replication. 1) Redis replication is asynchronous, bu ...

  7. LeetCode 595. Big Countries

    There is a table World +-----------------+------------+------------+--------------+---------------+ ...

  8. leveldb和fork的初始化顺序

    我们服务器内用leveldb存一些不是很重要的, 但是又需要(半)持久化的东西. 可是自从2016到现在, 碰见好几次不同类型的死锁. 直到今天, 才发现真正的原因, 那就是leveldb不支持for ...

  9. Python-类与对象

    类与对象的概念 类即类别.种类,是面向对象设计最重要的概念,从一小节我们得知对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体. 那么问题来了,先有的一个个具体存在的对象(比如一个具 ...

  10. SPA单页面优缺点

    优点: 1.体验好,不刷新,减少 请求  数据ajax异步获取 页面流程: 2.前后端分离 3.减轻服务端压力 4.共用一套后端程序代码,设配多端 缺点: 1.首屏加载过慢: 2.SEO 不利于搜索引 ...