简体   繁体   English

像其他资产一样通过 CDN URL 从动态导入中加载块

[英]Loading chunks from dynamic imports though CDN URL like other assets

I have a CDN pointing to my base domain, there is 1:1 mapping basically.我有一个指向我的基域的 CDN,基本上是 1:1 映射。 I'm trying to build my bundle on the server, and I want to load it using CDN URL.我正在尝试在服务器上构建我的包,我想使用 CDN URL 加载它。 What I want to have after npm run build is: npm run build后我想要的是:

public/
  css/
    app.css
  js/
    index.js
    1.js.gz
    1.js
    2.js.gz
    2.js

And then my CDN will reflect that, so I want these resources to be loaded like this:然后我的 CDN 会反映这一点,所以我希望像这样加载这些资源:

https://mycdn.com/public/js/index.js
https://mycdn.com/public/css/app.css

My current webpack.mix.js config:我当前的webpack.mix.js配置:

mix
  .sass('resources/sass/app.css', 'public/css')
  .js('resources/js/index.js', 'public/js')

It generates all files in the proper location, which is good.它会在正确的位置生成所有文件,这很好。 Then I include them in my index.blade.php :然后我将它们包含在我的index.blade.php中:

<script src="{{ elixirCDN('/js/index.js') }}"></script>

elixirCDN is my custom function: elixirCDN 是我自定义的 function:

function elixirCDN($file)
{
    $cdn = '';

    if(config('system.cdn_url'))
    {
        $cdn = config('system.cdn_url');
    }

    return $cdn . elixir($file);
}

It basically prepends filename with CDN url, so it all works fine.它基本上在文件名前加上 CDN url,所以一切正常。

The problem begins when I use dynamic imports, like this:当我使用动态导入时,问题就开始了,如下所示:

const Home = () => import("./Home")

The ideal situation would be that it also loads with the CDN:理想的情况是它还与 CDN 一起加载:

https://mycdn.com/public/js/1.js

but instead, it doesn't, it loads with a relative path and my base domain:但相反,它没有,它加载了一个相对路径和我的基域:

https://mybasedomain.com/public/js/1.js

Obviously, because it's dynamic.显然,因为它是动态的。 How can I make my chunks to be loaded from the CDN as well?我怎样才能让我的块也从 CDN 加载?

I've tried to set publicPath as my CDN url, but it doesn't have any effect.我尝试将publicPath设置为我的 CDN url,但它没有任何效果。 I've also tried setPublicPath() but it's the same.我也试过setPublicPath()但它是一样的。

Hi this is not the definitive answer but a step in the right direction.嗨,这不是明确的答案,而是朝着正确方向迈出的一步。 I got into this issue because my conditional import broke after updating all the webpack and babel packages.我遇到了这个问题,因为在更新所有 webpack 和 babel 包后,我的条件导入中断了。

Before the dynamic import you need to set the temporary public path for webpack to the location of the chunck which webpack needs to import dynamically动态导入前需要将webpack的临时公共路径设置为webpack需要动态导入的chunck的位置

__webpack_public_path__ = 'https://cdn.dev.acsi.eu/eurocampings/assets/dev/dist/';

Than the import works比进口作品

import(/* webpackChunkName: "state" */ './modules/BookingState/State')
        .then(({createState}) => {
            createState();
            this.renderEurocampingsWebsite(window);
        });

For me the dynamic import works, however it seems that the conditional import before, all the package updates, was working in without async behavior...对我来说,动态导入有效,但似乎之前的条件导入,所有 package 更新,都在没有异步行为的情况下工作......

Just found out that Webpack has more magical comments, which can make the code behave procedural, at the cost of having both modules imported for the conditional import.刚刚发现 Webpack 有更多神奇的注释,可以使代码表现程序化,代价是同时导入两个模块以进行条件导入。 This might also be helpful这也可能有帮助

import(
            /* webpackChunkName: "state" */
            /* webpackMode: "eager" */
            /* webpackPreload: true */
            './modules/BookingState/State'
        )
        .then...

I had a similar problem, where my main script was loaded into another page, and when loading chunks it tried loading them from the root url instead of the cdn.我有一个类似的问题,我的主脚本被加载到另一个页面中,并且在加载块时它尝试从根 url 而不是 cdn 加载它们。

Using the answer above, I came to the following solution:使用上面的答案,我得出以下解决方案:

in root imported file在根导入文件中

export function setWebpackToLoadChunksFromScriptUrl() {
  const scriptPath: string = (document.currentScript as any || {}).src;
  const loadPath = scriptPath ? scriptPath.substring(0, scriptPath.lastIndexOf('/')) : '';
  if (loadPath) {
    __webpack_public_path__ = loadPath;
  }
}
setWebpackToLoadChunksFromScriptUrl();

export async function loadApplication(elementId: string) {
  const { loadApplicationOnHtmlElement } = (await import('./loaded-app'));
  loadApplicationOnHtmlElement((elementId));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM