解决Vue项目打包后dist中的index.html用浏览器直接打开显示空白页的问题

目录

场景描述

问题分析

解决方案

vue-cli@2项目通过修改index.html引用路径或添加配置信息

方案一:将index.html中引用的绝对路径改为相对路径

方案二:修改项目的assetsPublicPath或添加publicPath配置信息

vue-cli@3项目通过修改index.html引用路径或添加配置信息

方案一:将index.html中引用的绝对路径改为相对路径

方案二:修改项目的publicPath配置信息在本地访问

vue-cli@2/3项目通过搭建本地服务器,实现本地访问

方案一、使用http-server静态服务器 

方案二、通过在dist目录中起服务访问

方案三、使用http模块,手写node服务器


  

场景描述

通过vue-cli创建的vue项目,npm run serve运行开发环境可以看到效果,但是执行 npm run bulid本地打包之后生成的dist文件下的index.html用浏览器无法直接打开,显示空白页,控制台有很多报错信息如下:GET file:///...... net::ERR_FILE_NOT_FOUND(vue-cli3创建vue项目)或是 Failed to load resource: net::ERR_FILE_NOT_FOUND(vue-cli2创建vue项目)

问题分析

可能有人会问,为什么打包后的dist文件夹里inde.html,在本地直接打开无法访问,要放在服务器的根目录才能打开,如何才能像访问 npm run dev(使用vue-cli2创建的vue项目的启动方式)或npm run serve(使用vue-cli3创建的vue项目的启动方式) 的地址那样访问?

首先,我们来解释一下vue脚手架项目启动项目的原理,其实,在你使用 npm run dev或npm run serve的时候,实际是临时创建了一个webpack-dev-server或vue-cli-service serve的node服务器,为了方面后面的 hot-reload(热重载)的需求,必须所有的更新都要在服务上处理后进行更新,如果你是单纯用file协议打开静态网站的方式,是没有办法做到这个处理的,如果可以,也是需要编译和重载的,成本很高昂。所以,vue通过npm run dev或npm run serve启动项目,也是以启动服务器的方式进行编译的。

我们之所以出现报错,这是因为打包的dist文件夹是需要放在服务器上运行的,资源默认放在根目录下。你打开index.html就可以发现,被打包成的css和js文件的引用使用的是绝对路径,例如: <link href="/css/app.8acb2246.css" rel="stylesheet"><script src="/js/chunk-vendors.da145e16.js"></script>,但对本地磁盘来说," " 指向的是磁盘根目录,所以,找不到引用的文件。因为当我们在本地使用file协议打开index.html是需要引用相对路径的静态资源。一句话来说,就是打包以后的index.html文件中的引用路径不对,才导致报错

解决方案

这里会介绍使用 vue-cil@2 和 vue-cil@3 两种方式创建vue项目的解决方案

有以下3种解决方案

方案一:将index.html中引用的绝对路径改为相对路径

方案二:修改或是添加项目的配置信息,实现本地访问 

方案三:通过搭建本地服务器,实现本地访问(3种方法)

vue-cli@2项目通过修改index.html引用路径或添加配置信息


有3种实现方案,推荐第二种方案! 

方案一:将index.html中引用的绝对路径改为相对路径

可以选择手动将index.html中所有引用资源的地方全部改成相对路径,例如:

<script type=text/javascript src=static/js/manifest.2ae2e69a05c33dfc65f8.js></script>
<script type=text/javascript src=static/js/vendor.5d4fc21e9bad685c9b37.js></script>
<script type=text/javascript src=static/js/app.394b37fa387958cd2f69.js></script>

方案二:修改项目的assetsPublicPath或添加publicPath配置信息

当然,更优雅的做法是修改项目的assetsPublicPath或添加publicPath配置信息,有3种方法,推荐第3种,如下:

1、修改config/index.js中build对象的assetsPublicPath,改为当前目录(./),而不是根目录(/);

module.exports = {
  ...

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',

    // 修改前
    // assetsPublicPath: '/',

    // 修改后:assetsPublicPath改为当前目录./
    assetsPublicPath: './',

    ...
  }
}

2、修改build/webpack.base.conf.js中的publicPath,在build/webpack.prod.conf.js添加publicPath 

* build/webpack.base.conf.js文件

output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    // 修改前
    // publicPath: process.env.NODE_ENV === 'production'
    //   ? config.build.assetsPublicPath
    //   : config.dev.assetsPublicPath

    // 修改后
    publicPath: process.env.NODE_ENV === 'production'
      ? './' + config.build.assetsPublicPath
      : './' + config.dev.assetsPublicPath
},

* build/webpack.prod.conf.js文件

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  // 修改前
  // output: {
  //   path: config.build.assetsRoot,
  //   filename: utils.assetsPath('js/[name].[chunkhash].js'),
  //   chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  // },

  // 修改后
  output: {
    publicPath: './',     // 添加的一行
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},

3、在 webpack.prod.conf.js 中的 output 对象添加参数publicPath:'./ '

具体代码如下:

const webpackConfig = merge(baseWebpackConfig, {
  ...
  output: {
    publicPath: process.env.NODE_ENV === 'production'
      ? './' +config.build.assetsPublicPath
      : './' + config.dev.assetsPublicPath,
    // 上面是添加代码
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  ...
})

以上方案一、二,都可以解决,此时再运行npm run build打包后,打开dist / index.html发现所有资源的引用路径已经变为相对路径了,此时可以双击index.html在浏览器中正常访问了!

vue-cli@3项目通过修改index.html引用路径或添加配置信息


有2种实现方案,推荐第二种方案! 

方案一:将index.html中引用的绝对路径改为相对路径

例如:

<link href="js/chunk-vendors.da145e16.js" rel="preload" as="script">
<link href="css/app.8acb2246.css" rel="stylesheet">
<script src="js/chunk-vendors.da145e16.js"></script>
<script src="js/app.1102999b.js"></script>

方案二:修改项目的publicPath配置信息在本地访问

当然,更优雅的做法是修改项目的publicPath配置信息,如下

1、在项目根目录新建 vue.config.js 文件,并添加publicPath: './ ' 

// vue.config.js
module.exports = {
  publicPath: './'
}

2、然后,关键的一步,在 src/router.js 中删去 mode: 'history'

...
export default new Router({
  // mode: 'history',  // 有这句的删掉,没有就不用管,因为默认mode: 'hash'模式
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    }
  ]
})

现在再次执行npm run build重新打包后,打开 dist下的 index.html就可以正常访问了

👉 番外:页面可以正常打开了,但是页面上的一些图片请求失败,怎么办

解决办法:在build/utils.js中,如下位置,添加 publicPath: '../../'

// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
  return ExtractTextPlugin.extract({
    use: loaders,
    fallback: "vue-style-loader",
    publicPath: "../../"
  });
}

👉 番外:页面可以正常打开了,如果vue-router跳转路由页面无法显示

解决方法:打开index.js看路由配置,mode:' hash ' 改这个配置即可:

//VueRouter's setting
export const router = new VueRouter({
  base: "/",
  mode: "hash",
  routes
});

 参考链接:解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题

vue-cli@2/3项目通过搭建本地服务器,实现本地访问


有3种搭建本地服务器实现方案,推荐第2种方案!

方案一、使用http-server静态服务器 

 http-server是一个简单的、零配置的命令行静态 HTTP 服务器。它足够强大,可以用于生产用途,但它足够简单且可破解,可用于测试、本地开发和学习。

用法查看官网:http-server - npm

http-server是一个基于命令行的简单的静态HTTP服务器,使用方法很简单:

① 安装

npm install http-server -g

② 进入dist文件夹

cd dist

③ 执行命令

http-server

大功告成!可以打开浏览器在localhost:8080中查看了。

方案二、通过在dist目录中起服务访问

使用express框架,搭建一个简单的nodejs服务器

step1:在dist 路径下,安装express包

npm install express

 step2:在dist文件中添加服务器app.js文件

var express = require("express");
var app = express();
const hostname = "localhost";
const port = 8080;
// Express 提供了内置的中间件 express.static 来设置静态文件
app.use(express.static("./"));
app.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}`);
});

step 3:命令行或是在终端运行

node app.js

方案三、使用http模块,手写node服务器

使用http模块只需要在文件中通过require(“http”) 引入即可。http模块是node.js原生模块中最为亮眼的模块。传统的HTTP服务器都会由nginx之类的软件来担任,但是node.js不需要。node.js的http模块本身就可以构建服务器,而且性能非常可靠。

◼️ 了解http模块:Node学习HTTP模块(HTTP 服务器与客户端)Node.js核心模块—http模块应用

我们可以使用nodejs原生的http模块,创建web服务器,在dist同级目录中新增文件server.js

// server.js
// 1. 引入接下来要用到的node内置模块
const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("fs");

// 2. 利用path解析当前目录,然后拼接dist目录,使得服务器当前的根目录变为dist
const root = path.join(path.resolve(process.argv[2] || "."), "dist");

// 3. 创建http服务器
const server = http.createServer((request, response) => {
  // 4. 解析请求url获取文件路径
  const pathname = url.parse(request.url).pathname;
  const filepath = path.join(root, pathname);

  // 5. 使用fs文件系统模块读取index.html文件并返回给前端
  fs.stat(filepath, (err, stats) => {
    if (!err && stats.isFile()) {
      // 响应头设为200
      response.writeHead(200);
      // 创建一个读写流管道,将index.html文件内容写入response并返回
      fs.createReadStream(filepath).pipe(response);
    } else {
      // 请求路径不对时返回404
      response.writeHead(404);
      response.end("404 Not Found");
    }
  });
});

// 6. 服务器监听8080端口
server.listen(8080);

命令行定位到app.js同级目录中执行node app.js,此时,在浏览器中可以访问http://localhost:8080/index.html查看效果。 


参考资料

vue本地打开打包后生成index.html无法显示内容

解决vue项目打包后打开index.html文件一片空白

你遇到的问题可能是由于未正确配置插件或使用错误的方法导致的。以下是一个示例代码片段,展示如何在Vue使用pdfjs-dist插件来显示PDF文件: 首先,确保你已经安装了pdfjs-dist插件。可以通过运行以下命令来安装它: ```shell npm install pdfjs-dist ``` 然后,在你的Vue组件,可以按照以下步骤来加载和显示PDF文件: 1. 导入pdfjs-dist插件: ```javascript import pdfjsLib from 'pdfjs-dist' ``` 2. 在需要显示PDF的地方,定义一个canvas元素: ```html <canvas id="pdfCanvas"></canvas> ``` 3. 在Vue组件的方法,加载并显示PDF文件: ```javascript loadPDF() { const canvas = document.getElementById('pdfCanvas'); const context = canvas.getContext('2d'); // 设置PDF文件路径 const pdfPath = 'your_pdf_path.pdf'; // 加载PDF文件 pdfjsLib.getDocument(pdfPath).promise.then(pdf => { // 获取第一页 pdf.getPage(1).then(page => { const viewport = page.getViewport({ scale: 1 }); canvas.width = viewport.width; canvas.height = viewport.height; // 渲染页面内容到canvas上下文 page.render({ canvasContext: context, viewport: viewport }); }); }); } ``` 4. 在Vue组件的`mounted`生命周期钩子,调用`loadPDF`方法来加载并显示PDF文件: ```javascript mounted() { this.loadPDF(); } ``` 请注意,上述代码只是一个示例,你需要根据你的实际需求进行适当的修改。确保替换`'your_pdf_path.pdf'`为你的PDF文件路径。 希望这可以帮助你解决问题!如果你有任何进一步的问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值