Open r4m-davronu opened 6 months ago
I have 2 applications for my single-spa
First application webpack.config.js:
{ mode: vars.webpackMode, entry: options.webpackEntries, experiments: { outputModule: true, }, output: { path: path.resolve(options.appPath, buildDirectory, vars.publicSubDir), publicPath: vars.publicPath, filename: vars.prodBuild ? '[name].[contenthash:8].js' : 'js/[name].js', module: true }, cache: vars.prodBuild ? false : { type: 'memory', cacheUnaffected: true, }, snapshot: { managedPaths: [/^(.+?[\\/]node_modules)[\\/]((?!@route4me)).*[\\/]*/], }, target: ['web', 'browserslist'], externals: { ...options.webpackExternal }, resolve: { alias: options.webpackAliases, extensions: [ '.ts', '.js', '.vue', '.json', ], }, module: { rules: [ // es { test: /\.m?js$/, exclude(modulePath) { const es6sourcesRegExpArray = [ /r4m-shared-ui[\\/]src/, /node_modules[\\/]vuetify/, ]; if (es6sourcesRegExpArray.filter(es6path => es6path.test(modulePath)).length > 0) { return false; } return /(node_modules|\.min\.)/.test(modulePath); }, use: [ { loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', ], ], plugins: [ '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-syntax-dynamic-import', '@babel/plugin-transform-parameters', ], cacheDirectory: true, }, }, ], }, { test: /\.(ts)$/, loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/], allowTsInNodeModules: true, context: path.resolve(options.appPath), compilerOptions: { outDir: path.resolve(options.appPath, buildDirectory, vars.publicSubDir), }, }, }, // VUE { test: /\.vue$/, loader: 'vue-loader', options: { loader: { scss: 'vue-style-loader!css-loader!sass-loader', }, }, }, // CSS & SCSS { test: /\.(css|scss)$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { importLoaders: 1, sourceMap: true, }, }, { loader: 'postcss-loader', options: { postcssOptions: { plugins: [ require('autoprefixer'), ], }, }, }, { loader: 'sass-loader', options: sassLoaderOptions, }, ], }, // WOFF FONTS { test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader', options: { name: vars.prodBuild ? '[name].[contenthash:8].[ext]' : '[name].[ext]', outputPath: 'fonts/', }, }, // IMAGES { test: /\.(png|svg|jpe?g|gif)$/, loader: 'file-loader', options: { name: vars.prodBuild ? '[name].[hash].[ext]' : '[name].[ext]', outputPath: 'img/', // publicPath: 'img/', // don't override, it's ok for referencing from CSS/SCSS ONLY! Not JS/Vue! }, }, ], }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: vars.prodBuild ? '[name].[contenthash:8].css' : '[name].css', // chunkFilename: vars.prodBuild ? '[id].[contenthash:8].css' : '[id].css', }), new VueLoaderPlugin({ optimizeSSR: false, }), new VuetifyLoaderPlugin(), new AssetsPlugin({ path: path.resolve(options.appPath, 'storage', 'json'), filename: 'assets.json', prettyPrint: true, entrypoints: true, }), vars.prodBuild && new BundleAnalyzerPlugin({ analyzerMode: 'static', reportFilename: path.resolve(options.appPath, 'bundle_report.html'), openAnalyzer: false, }), vars.hmr ? new webpack.HotModuleReplacementPlugin() : undefined, ].filter(Boolean), devtool: vars.prodBuild ? 'nosources-source-map' : 'eval-source-map', devServer: { static: { directory: options.appPath, }, devMiddleware: { writeToDisk: true, }, server: vars.wdsUrl.match(/https:/i) ? { type: 'https', options: { cert: './ssl.crt', key: './ssl.key', }, } : false, allowedHosts: "all", port: vars.wdsPort, compress: true, client: { overlay: false, }, headers: { 'Access-Control-Allow-Origin': vars.appUrl, 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization', 'Access-Control-Allow-Credentials': 'true', }, } }
First application main.js:
const vueLifecycles = singleSpaVue({ Vue, appOptions: { render: (h) => h(App), }, }); export const bootstrap = vueLifecycles.bootstrap; export const mount = vueLifecycles.mount; export const unmount = vueLifecycles.unmount;``` First application package.json: { "private": false, "scripts": { "start": "npm run serve", "build": "webpack", "serve": "webpack-dev-server", "create_env_webpack": "echo \"No need\" && exit 0", "test": "echo \"Error: no test specified\" && exit 1", "translate": "node node_modules/r4m-shared-ui/src/utils/translate-json.js", "lint": "eslint \"src/**/*.{js,vue}\" --fix" }, "engines": { "node": ">=14.0.0 <15.0.0", "npm": ">=6.0.0 <7.0.0", "yarn": "forbidden" }, "author": "", "license": "license.md", "dependencies": { "@mdi/font": "^5.9.55", "@mdi/js": "^5.9.55", "@vue/composition-api": "^1.7.2", "axios": "^0.26.1", "dayjs": "^1.11.10", "laravel-echo": "^1.8.1", "lodash": "^4.17.21", "promise-polyfill": "^8.1.3", "pusher-js": "^7.0.0", "qs": "^6.9.4", "single-spa": "^6.0.1", "sweetalert2": "^8.16.3", "systemjs-webpack-interop": "^2.3.7", "throttle-debounce": "^5.0.0", "vue": "2.6.14", "vue-axios": "^2.1.5", "vue-class-component": "^7.2.6", "vue-i18n": "^8.28.2", "vue-property-decorator": "^8.5.1", "vue2-perfect-scrollbar": "^1.5.56", "vuetify": "^2.1.9", "ws": "^8.16.0" }, "devDependencies": { "@babel/core": "^7.5.5", "@babel/plugin-proposal-object-rest-spread": "^7.5.5", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/preset-env": "^7.5.5", "@types/lodash": "^4.14.150", "@types/node": "^16.9.2", "@types/throttle-debounce": "^5.0.2", "@typescript-eslint/eslint-plugin": "^2.34.0", "@typescript-eslint/parser": "^2.34.0", "@vue/eslint-config-typescript": "^5.1.0", "assets-webpack-plugin": "^7.1.1", "autoprefixer": "^9.7.3", "babel-eslint": "^10.0.3", "babel-loader": "^8.0.6", "browserslist": "^4.23.0", "clean-webpack-plugin": "^3.0.0", "css-loader": "^2.1.1", "css-minimizer-webpack-plugin": "^6.0.0", "dotenv-flow": "^3.1.0", "eslint": "^5.16.0", "eslint-config-airbnb-base": "^13.2.0", "eslint-config-vuetify": "^0.4.0", "eslint-import-resolver-webpack": "^0.11.1", "eslint-loader": "^2.2.1", "eslint-plugin-import": "^2.18.2", "eslint-plugin-vue": "^5.2.3", "eslint-plugin-vuetify": "^1.0.0-beta.5", "file-loader": "^4.2.0", "fs": "0.0.1-security", "html-webpack-plugin": "^5.6.0", "mini-css-extract-plugin": "^0.7.0", "node-fetch": "^2.6.7", "optimize-css-assets-webpack-plugin": "^5.0.3", "postcss-loader": "^3.0.0", "sass": "~1.32.0", "sass-loader": "^8.0.0", "style-loader": "^1.0.0", "terser-webpack-plugin": "^5.3.10", "ts-loader": "^9.5.1", "typescript": "^4.9.5", "url-loader": "^1.1.2", "v-mask": "^2.3.0", "vue-eslint-parser": "^6.0.4", "vue-loader": "15.9.2", "vue-style-loader": "^4.1.2", "vue-template-compiler": "2.6.14", "vuetify-loader": "1.5.0", "webpack": "^5.90.3", "webpack-bundle-analyzer": "^4.10.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.2" }, "babel": { "presets": [ "@babel/preset-env" ] } }
bootstrap, mount, unmount - exists on main.ts at all.
But when i add this application to single-spa like this:
<script type="systemjs-importmap"> { "imports": { ... "app1": "http://localhost:9000/js/app.js", ... } } </script> ... ... ... singleSpa.registerApplication( 'app1', async () => { const sc = await System.import('app1'); console.log('first application', sc) return System.import('app1') }, location => true )
console returns me not Module, only error: Uncaught app1: Application 'app1' died in status LOADING_SOURCE_CODE: "does not export an unmount function or array of functions"
Second application with boilerplate vue-cli works perfectly.
How to fix my application on webpack?
look at screen (don't pay attention to the app name)
@joeldenning look please
I have 2 applications for my single-spa
First application webpack.config.js:
First application main.js:
bootstrap, mount, unmount - exists on main.ts at all.
But when i add this application to single-spa like this:
console returns me not Module, only error: Uncaught app1: Application 'app1' died in status LOADING_SOURCE_CODE: "does not export an unmount function or array of functions"
Second application with boilerplate vue-cli works perfectly.
How to fix my application on webpack?