Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialization of sharing external failed: ScriptExternalLoadError: Loading script failed. #692

Closed
Ge-yuan-jun opened this issue Feb 4, 2021 · 18 comments

Comments

@Ge-yuan-jun
Copy link

webpack version: 5.20.0

error message

warining: Initialization of sharing external failed: ScriptExternalLoadError: Loading script failed.
error: Uncaught (in promise) ScriptExternalLoadError: Loading script failed.

image

similar issue: (#307)

I already used syntax like app2: "app2@http://localhost:3002/remoteEntry.js" , but the browser still report the error.

Here's my config:

app1

image
image

app2

image

image

other

I am sure I have read shared-routes2 folder in this repo.

The difference between my demo and shared-routes is this different framework.

I use vue-cli in my demo.

I inspect the generated webpack config:

/* config.plugin('mf') */
// app1
new ModuleFederationPlugin(
  {
    name: 'app1',
    filename: 'remoteEntry.js',
    remotes: {
      app2: 'app2@http://localhost:8082/remoteEntry.js'
    },
    exposes: {},
    shared: {
      vue: {
        eager: true,
        singleton: true,
        requiredVersion: '^2.6.11'
      },
      'vue-router': {
        eager: true,
        singleton: true,
        requiredVersion: '^3.4.3'
      }
    }
  }
)

// app2
/* config.plugin('mf') */
new ModuleFederationPlugin(
  {
    name: 'app2',
    filename: 'remoteEntry.js',
    exposes: {
      './routes': './src/router/index.ts'
    },
    shared: {
      vue: {
        eager: true,
        singleton: true,
        requiredVersion: '^2.6.11'
      },
      'vue-router': {
        eager: true,
        singleton: true,
        requiredVersion: '^3.4.3'
      }
    }
  }
)
@Ge-yuan-jun
Copy link
Author

When I use config
library: { type: 'var', name: 'app2' },

It changes to another error:
app.js:62 Uncaught (in promise) ReferenceError: app2 is not defined while loading "./routes" from webpack/container/reference/app2

image

@Ge-yuan-jun
Copy link
Author

@ScriptedAlchemy Very sorry to bother you

can you help with some config advice?

or need some more config info ?

@jacob-ebey
Copy link
Member

jacob-ebey commented Feb 7, 2021

library: { type: "var", name: "app2" }

then try manually adding the remoteEntry. That error says "it's not defined", meaning the remote entry was not loaded before webpack tried to access it.

@Ge-yuan-jun
Copy link
Author

Ge-yuan-jun commented Feb 7, 2021

@jacob-ebey Sorry to interrupt you

I tried your advice, emmm, the error above disappears;

but, another error occurs, it say 'Uncaught (in promise) Error: Container missing
while loading "./routes" from webpack/container/reference/app2'

image

may I have more advice ?

manually adding the remoteEntry code:

loadScript('http://localhost:8082/remoteEntry.js').then(() => {
  import('./bootstrap')
})

@Ge-yuan-jun
Copy link
Author

Finally, it's not webpack config error. I create a demo here

the problem related to vue-cli & vue.config.js, but I cannot find out the reason why it failed in vue-cli so far.

For me, I will create a PR for vue3-demo, it doesn't contain how to use routes in remote repo.

this issue closed

@HolyZheng
Copy link

Finally, it's not webpack config error. I create a demo here

the problem related to vue-cli & vue.config.js, but I cannot find out the reason why it failed in vue-cli so far.

For me, I will create a PR for vue3-demo, it doesn't contain how to use routes in remote repo.

this issue closed

兄弟,有发现问题吗?我现在也遇到同样的问题

@HolyZheng
Copy link

Finally, it's not webpack config error. I create a demo here
the problem related to vue-cli & vue.config.js, but I cannot find out the reason why it failed in vue-cli so far.
For me, I will create a PR for vue3-demo, it doesn't contain how to use routes in remote repo.
this issue closed

兄弟,有发现问题吗?我现在也遇到同样的问题

我这边发现问题了,是qiannkun沙箱问题,暂时通过配置library: { type: 'window', name: 'xxx' } 来解决

@nzinovyev19
Copy link

I'm using vue-cli with vue3 and disabling splitChunks was the solution for me.
#vuejs/vue-cli#6318 (comment)

@popuguytheparrot
Copy link

how a u resolve it?

@udittyagi
Copy link

Hello I am facing same issue
Remote Webpack Config
`const merge = require('webpack-merge');
const common = require('./webpack.config.js');
const deps = require('../package.json').dependencies;
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
output: {
publicPath: 'http://localhost:3000/v2/assets/dist/'
},
optimization: {
splitChunks: {
cacheGroups: {
defaultVendors: false
}
}
},
plugins: [
new CleanWebpackPlugin(['./assets/dist'], {
root: path.resolve(__dirname, '../')
}),

	new AssetsPlugin({ filename: 'build_assets/react.json', prettyPrint: true }),
	new ModuleFederationPlugin({
		name: 'corpAdmin',
		filename: 'remoteEntry.js',
		exposes: {
			'./BizLanding': './src/bizLanding/bootstrap.js'
		},
		shared: {
			'react': {
				eager: true,
				singleton: true,
				requiredVersion: deps.react
			},
			'react-dom': {
				eager: true,
				singleton: true,
				requiredVersion: deps['react-dom']
			}
		}
	})
],
devServer: {
	contentBase: './assets/dist'
}

});
`

Host Webpack config
`const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin
const deps = require("./package.json").dependencies;

module.exports = {
//Where files should be sent once they are bundled
output: {
path: path.join(__dirname, '/dist'),
filename: 'index.bundle.js',
publicPath: "http://localhost:3005/",
},
//webpack 5 comes with devServer which loads in development mode
devServer: {
port: 3005,
watchContentBase: true
},
//Rules of how webpack will take our files, complie & bundle them for the browser
module: {
rules: [
{
test: /.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
},
},
{
test: /.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new ModuleFederationPlugin({
name: 'corpAnother',
filename: 'remoteEntry.js',
remotes: {},
exposes: {
'./Header': './src/App.js'
},
shared: {
...deps,
'react': {
eager: true,
singleton: true,
requiredVersion: deps.react
},
'react-dom': {
eager: true,
singleton: true,
requiredVersion: deps['react-dom']
}
}
}),
new HtmlWebpackPlugin({ template: './src/index.html' }),
new MiniCssExtractPlugin()],
}`

Uncaught ScriptExternalLoadError: Loading script failed.
(missing: http://localhost:3000/v2/assets/dist/remoteEntry.js)
while loading "./BizLanding" from webpack/container/reference/corpAdmin
at Object.webpack/container/reference/corpAdmin (index.bundle.js:474)
at webpack_require (index.bundle.js:511)
at initExternal (index.bundle.js:782)
at Function.webpack_require.I (index.bundle.js:795)
at index.bundle.js:901
at Object.webpack/sharing/consume/default/react-dom/react-dom (index.bundle.js:947)
at index.bundle.js:985
at Array.forEach ()
at Object.webpack_require.f.consumes (index.bundle.js:968)
at index.bundle.js:588

/src/bizLanding/bootstrap.js
import React from 'react';

const BizLandingApp = () => (


Hello App From Another Application



);

export default BizLandingApp;

@ScriptedAlchemy
Copy link
Member

Public path is probably incorrect

@huntJs
Copy link

huntJs commented Apr 27, 2022

Finally, it's not webpack config error. I create a demo here
the problem related to vue-cli & vue.config.js, but I cannot find out the reason why it failed in vue-cli so far.
For me, I will create a PR for vue3-demo, it doesn't contain how to use routes in remote repo.
this issue closed

兄弟,有发现问题吗?我现在也遇到同样的问题

我这边发现问题了,是qiannkun沙箱问题,暂时通过配置library: { type: 'window', name: 'xxx' } 来解决

请问你这边qiankun项目是如何使用MF,可以分享下一个demo吗

@gabrielmaschke
Copy link

As mentioned by nrz2000 disabling splitChunks worked, but I didn't understand why, so I checked vue-cli code to see how they were configuring SplitChunks plugin.

And here it is what I got so far:

Comparing the config from vue-cli and the default webpack config from the official website we can get some answers.

Code copied from vue-cli:

https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/lib/config/app.js#L41-L60

      webpackConfig.optimization.splitChunks({
        cacheGroups: {
          defaultVendors: {
            name: `chunk-vendors`,
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            chunks: 'initial'
          },
          common: {
            name: `chunk-common`,
            minChunks: 2,
            priority: -20,
            chunks: 'initial',
            reuseExistingChunk: true
          }
        }
      })

Code copied from webpack docs:

https://webpack.js.org/plugins/split-chunks-plugin/#optimizationsplitchunks

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

So the main difference between the two configs is that webpack uses by default chunks: 'async' while vue-cli uses chunks: initial, and this seems to be the reason behind the error with module federation. I changed my vue-config to the following and it solved the problem:

Note that it's the same configuration as vue-cli, but just changing the chunks property on both cache groups from initial to async

optimization: {
      splitChunks: {
        cacheGroups: {
          defaultVendors: {
            name: `chunk-vendors`,
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            chunks: 'async',
            reuseExistingChunk: true
          },
          common: {
            name: `chunk-common`,
            minChunks: 2,
            priority: -20,
            chunks: 'async',
            reuseExistingChunk: true
          }
        }
      }
    }

Still, I don't know the specific reason, in this stackoverflow thread they explain the differences between the three possible split chunk values: async, all and initial. I tried with 'all' and the error persists. I think it's related to the nature of module federation that relies on async chunks, so trying optimizing static chunks throw errors, but I'm just speculating here. Hope someone has some answers.

@ScriptedAlchemy
Copy link
Member

Chunks also accepts function. So all, initial, async or function. Use function and test chunks to see if they contain remote-module or provide-module type, return false for those and true for any others. That lets you exclude MF manages chunks from split chunks algorithms

@tsunamiShi
Copy link

Finally, it's not webpack config error. I create a demo here
the problem related to vue-cli & vue.config.js, but I cannot find out the reason why it failed in vue-cli so far.
For me, I will create a PR for vue3-demo, it doesn't contain how to use routes in remote repo.
this issue closed

兄弟,有发现问题吗?我现在也遇到同样的问题

我这边发现问题了,是qiannkun沙箱问题,暂时通过配置library: { type: 'window', name: 'xxx' } 来解决

相关issue

@burhanuday
Copy link
Contributor

based on @gabrielmaschke and @ScriptedAlchemy 's solution, the following worked for me

common: {
    name: `chunk-common`,
    minChunks: 3,
    enforce: true,
    priority: -20,
    chunks: 'async',
    reuseExistingChunk: true,
    test(module) {
        if (
            module.type === 'provide-module' ||
            module.type === 'consume-shared-module' ||
            module.type === 'remote-module'
        ) {
            return false;
        }
        return true;
    }
}

I am not sure how to fix this in webpack. since all module types are derived classes of Module, they get sent to the SplitChunksPlugin. It does not make sense to add a condition in the SplitChunksPlugin to check for this but I cant find where else to fix it
@ScriptedAlchemy any help here?
If we cant fix this, I am willing to send a PR to the docs to add this to the troubleshooting section because this is important from a loading time pov

@ScriptedAlchemy
Copy link
Member

Not necessarily since I still want the option to be able to manipulate the chunking algorithm for federated module chunks too. So I don't want to skip it from split chunks.

Maybe a default option can be added though.

@burhanuday
Copy link
Contributor

manipulate the chunking algorithm for federated module chunks too

Manipulate only provide-modules or the other ones as well?

From my understanding, consume-shared-module and remote-module break the build when added to split chunks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests