diff options
-rw-r--r-- | .github/workflows/buildvue.yml | 4 | ||||
-rw-r--r-- | core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php | 46 | ||||
-rw-r--r-- | plugins/CoreHome/vue/dist/umd.metadata.json | 3 | ||||
-rw-r--r-- | plugins/ExampleVue/vue/dist/umd.metadata.json | 5 | ||||
-rw-r--r-- | plugins/Feedback/vue/dist/umd.metadata.json | 5 | ||||
-rw-r--r-- | vue.config.js | 37 |
6 files changed, 91 insertions, 9 deletions
diff --git a/.github/workflows/buildvue.yml b/.github/workflows/buildvue.yml index 95c9dc26e1..d0d268df43 100644 --- a/.github/workflows/buildvue.yml +++ b/.github/workflows/buildvue.yml @@ -127,10 +127,10 @@ jobs: if: steps.vars.outputs.branch != '' && steps.vuecheck.outputs.vue_modified == '1' - name: Push changes run: | - if [[ $( git diff --numstat plugins/*/vue/dist/*.js plugins/*/vue/dist/*.map ) ]] + if [[ $( git diff --numstat plugins/*/vue/dist/*.js plugins/*/vue/dist/*.json ) ]] then cd $GITHUB_WORKSPACE - git add plugins/*/vue/dist/*.js + git add plugins/*/vue/dist/*.js plugins/*/vue/dist/*.json git commit -m "built vue files" git push fi diff --git a/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php b/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php index 84484ab0d3..b720aca33c 100644 --- a/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php +++ b/core/AssetManager/UIAssetFetcher/JScriptUIAssetFetcher.php @@ -97,15 +97,57 @@ class JScriptUIAssetFetcher extends UIAssetFetcher private function addUmdFilesIfDetected($plugins) { + $plugins = $this->orderPluginsByPluginDependencies($plugins); + foreach ($plugins as $plugin) { $devUmd = "plugins/$plugin/vue/dist/$plugin.development.umd.js"; $minifiedUmd = "plugins/$plugin/vue/dist/$plugin.umd.min.js"; if (Development::isEnabled() && is_file(PIWIK_INCLUDE_PATH . '/' . $devUmd)) { - $this->fileLocations[] = $devUmd; + $this->fileLocations[$plugin] = $devUmd; } else if (is_file(PIWIK_INCLUDE_PATH . '/' . $minifiedUmd)) { - $this->fileLocations[] = $minifiedUmd; + $this->fileLocations[$plugin] = $minifiedUmd; + } + } + } + + private function orderPluginsByPluginDependencies($plugins) + { + $result = []; + + while (!empty($plugins)) { + $this->visitPlugin(reset($plugins), $plugins, $result); + } + + return $result; + } + + private function visitPlugin($plugin, &$plugins, &$result) + { + // remove the plugin from the array of plugins to visit + $index = array_search($plugin, $plugins); + if ($index !== false) { + unset($plugins[$index]); + } else { + return; // already visited + } + + // read the plugin dependencies, if any + $umdMetadata = "plugins/$plugin/vue/dist/umd.metadata.json"; + + $pluginDependencies = []; + if (is_file($umdMetadata)) { + $pluginDependencies = json_decode(file_get_contents($umdMetadata), true); + } + + if (!empty($pluginDependencies['dependsOn'])) { + // visit each plugin this one depends on first, so it is loaded first + foreach ($pluginDependencies['dependsOn'] as $pluginDependency) { + $this->visitPlugin($pluginDependency, $plugins, $result); } } + + // add the plugin to the load order after visiting its dependencies + $result[] = $plugin; } } diff --git a/plugins/CoreHome/vue/dist/umd.metadata.json b/plugins/CoreHome/vue/dist/umd.metadata.json new file mode 100644 index 0000000000..c63babfe11 --- /dev/null +++ b/plugins/CoreHome/vue/dist/umd.metadata.json @@ -0,0 +1,3 @@ +{ + "dependsOn": [] +}
\ No newline at end of file diff --git a/plugins/ExampleVue/vue/dist/umd.metadata.json b/plugins/ExampleVue/vue/dist/umd.metadata.json new file mode 100644 index 0000000000..9ecfcc0456 --- /dev/null +++ b/plugins/ExampleVue/vue/dist/umd.metadata.json @@ -0,0 +1,5 @@ +{ + "dependsOn": [ + "CoreHome" + ] +}
\ No newline at end of file diff --git a/plugins/Feedback/vue/dist/umd.metadata.json b/plugins/Feedback/vue/dist/umd.metadata.json new file mode 100644 index 0000000000..9ecfcc0456 --- /dev/null +++ b/plugins/Feedback/vue/dist/umd.metadata.json @@ -0,0 +1,5 @@ +{ + "dependsOn": [ + "CoreHome" + ] +}
\ No newline at end of file diff --git a/vue.config.js b/vue.config.js index 4755a75fff..a758b2378e 100644 --- a/vue.config.js +++ b/vue.config.js @@ -26,7 +26,7 @@ if (!process.env.MATOMO_CURRENT_PLUGIN) { const publicPath = `plugins/${process.env.MATOMO_CURRENT_PLUGIN}/vue/dist/`; // hack to get publicPath working for lib build target (see https://github.com/vuejs/vue-cli/issues/4896#issuecomment-569001811) -function PublicPathWebpackPlugin () {} +function PublicPathWebpackPlugin() {} PublicPathWebpackPlugin.prototype.apply = function (compiler) { compiler.hooks.entryOption.tap('PublicPathWebpackPlugin', (context, entry) => { @@ -45,13 +45,40 @@ PublicPathWebpackPlugin.prototype.apply = function (compiler) { }); }; +const detectedDependentPlugins = []; + +function OutputDetectedDependentPluginsPlugin() {} +OutputDetectedDependentPluginsPlugin.prototype.apply = function (compiler) { + compiler.hooks.afterCompile.tap('OutputDetectedDependentPluginsPlugin', (context, entry) => { + const metadataPath = path.join(__dirname, publicPath, 'umd.metadata.json'); + const metadata = { + dependsOn: detectedDependentPlugins, + }; + fs.mkdirSync(path.dirname(metadataPath), { recursive: true }); + fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); + }); +}; + module.exports = { publicPath, chainWebpack: config => { - config.plugin().use(PublicPathWebpackPlugin); - config.externals({ - 'tslib': 'tslib', - ...pluginExternals, + config.plugin('output-detected-dependent-plugins').use(OutputDetectedDependentPluginsPlugin); + config.plugin('public-path-webpack').use(PublicPathWebpackPlugin); + config.externals(function (context, request, callback) { + if (request === 'tslib') { + callback(null, 'tslib'); + return; + } + + if (pluginExternals[request]) { + if (detectedDependentPlugins.indexOf(request) === -1) { + detectedDependentPlugins.push(request); + } + callback(null, pluginExternals[request]); + return; + } + + callback(); }); }, }; |