Django Webpack Loader 破坏 Vue 路由器链接

Posted

技术标签:

【中文标题】Django Webpack Loader 破坏 Vue 路由器链接【英文标题】:Django Webpack Loader Breaking Vue Router Links 【发布时间】:2019-12-26 23:52:35 【问题描述】:

短版 当我访问 localhost 时,我的 django/vue 应用程序呈现良好。但是当我点击一个链接时,由于我的 webpack 和vue.config.js 设置,我没有被带到localhost/about,而是被带到http://localhost/http:/0.0.0.0:8080/about

详情 我有一个应用程序在后端运行(在 docker-compose 中)Django,在前端运行 Vue。该应用程序使用 django-webpack-loader 和 webpack-bundle-tracker 在 Django 中呈现应用程序。

# Django settings.py
WEBPACK_LOADER = 
    "DEFAULT": 
        "CACHE": DEBUG,
        "BUNDLE_DIR_NAME": "/bundles/",
        "STATS_FILE": os.path.join(FRONTEND_DIR, "webpack-stats.json"),
    

# Django urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, re_path
from django.views.generic import TemplateView

urlpatterns = [
    path("admin/", admin.site.urls),
    re_path("^.*$", TemplateView.as_view(template_name="application.html"), name="app"),
]
if settings.DEBUG:
    urlpatterns = (
        urlpatterns
        + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
        + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    )
<!-- Template -->
% load render_bundle from webpack_loader %
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="/favicon.ico">
    <title>My Website</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons">
  </head>
  <body>
    <noscript>
      <strong>We're sorry but this application doesn't work properly without javascript enabled. Please enable it to continue.</strong>
    </noscript>
        <div id="app">
             <app></app>
         </div>% render_bundle 'app' %<!-- built files will be auto injected -->
  </body>
</html>
// vue.config.js
const BundleTracker = require("webpack-bundle-tracker");

module.exports = 
  publicPath:
    process.env.NODE_ENV === "production"
      ? "https://example.com"
      : "http://0.0.0.0:8080/",
  outputDir: "./dist/",

  chainWebpack: config => 
    config.optimization.splitChunks(false);

    config
      .plugin("BundleTracker")
      .use(BundleTracker, [ filename: "webpack-stats.json" ]);

    config.resolve.alias.set("__STATIC__", "static");

    config.devServer
      .public("http://0.0.0.0:8080")
      .host("0.0.0.0")
      .port(8080)
      .hotOnly(true)
      .watchOptions( poll: 500 )
      .https(false)
      .headers( "Access-Control-Allow-Origin": ["*"] );
  
;

当我启动应用程序时,访问 localhost 工作正常,但如果我尝试单击其中一个 vuetify 链接,它会将我带到 http://localhost/http:/0.0.0.0:8080/about(可能是因为这是我指定为 publicPath 的 URL开发环境)。如果我用http://0.0.0.0 替换localhost,我会得到同样不希望的重定向到http://0.0.0.0/http:/0.0.0.0:8080/。但是,如果我访问 localhost:8080,我可以浏览应用程序并点击链接到它们的正确位置(例如 localhost:8080/about)。

我尝试删除publicPath 的配置,但是当我这样做时,Django 应用程序无法为 vue 应用程序提供服务:该应用程序在 app.js 中加载一个带有 SyntaxError: expected expression, got '&lt;' javascript 错误的空白页面。我认为这是因为它试图加载http://0.0.0.0/app.js 并接收http://0.0.0.0 提供的相同模板响应。

所以我想我有几个选择: 1)我应该保留默认的vue.config.jspublicPath选项,并配置django从正确的位置提供app.js(如果是这样,那个位置是什么?) 2)我可以配置vue路由器使用与publicPath中指定的不同的根URL吗?

如果这种配置不可行,我可以切换到在 Nuxt 而不是 Django 中进行 s-s-r,但我很想了解更多关于这里存在什么样的配置问题。

【问题讨论】:

【参考方案1】:

我相信可以通过添加解决

mode: "history",

到你的 router.js 文件。

【讨论】:

【参考方案2】:

您可以将 vue 路由器配置为使用不同的根 URL。 只需在 router.js 中替换

base: process.env.BASE_URL,

base: '/',

【讨论】:

似乎对构建没有影响。它仍然请求/js/ 而不是/static/js

以上是关于Django Webpack Loader 破坏 Vue 路由器链接的主要内容,如果未能解决你的问题,请参考以下文章

图片资源压缩

图片资源压缩

webpack中loader为啥是从后往前加载的

webpack loader使用

二、webpack的loader配置

webpack常用loader和plugin