diff --git a/generators/client/files-vue.js b/generators/client/files-vue.js index fdd744b9aa1..8d5216a1824 100644 --- a/generators/client/files-vue.js +++ b/generators/client/files-vue.js @@ -25,6 +25,7 @@ const { GATEWAY } = require('../../jdl/jhipster/application-types'); const { CLIENT_MAIN_SRC_DIR, CLIENT_TEST_SRC_DIR, VUE_DIR } = constants; module.exports = { + cleanup, writeFiles, customizeFiles, }; @@ -37,15 +38,11 @@ const vueFiles = { 'tsconfig.json', '.postcssrc.js', '.eslintrc.js', - 'webpack/env.js', - 'webpack/dev.env.js', - 'webpack/prod.env.js', + 'webpack/config.js', 'webpack/webpack.common.js', 'webpack/webpack.dev.js', 'webpack/webpack.prod.js', 'webpack/vue.utils.js', - 'webpack/loader.conf.js', - 'webpack/utils.js', ], }, { @@ -323,6 +320,18 @@ const vueFiles = { ], }; +function cleanup() { + if (!this.clientFrameworkVue) return; + + if (this.isJhipsterVersionLessThan('7.3.1')) { + this.removeFile('webpack/env.js'); + this.removeFile('webpack/dev.env.js'); + this.removeFile('webpack/prod.env.js'); + this.removeFile('webpack/utils.js'); + this.removeFile('webpack/loader.conf.js'); + } +} + function writeFiles() { // write Vue files return this.writeFilesToDisk(vueFiles, 'vue'); diff --git a/generators/client/index.js b/generators/client/index.js index 87f9ea5e956..71aaaa798ac 100644 --- a/generators/client/index.js +++ b/generators/client/index.js @@ -23,7 +23,7 @@ const BaseBlueprintGenerator = require('../generator-base-blueprint'); const prompts = require('./prompts'); const writeAngularFiles = require('./files-angular').writeFiles; const writeReactFiles = require('./files-react').writeFiles; -const { writeFiles: writeVueFiles, customizeFiles: customizeVueFiles } = require('./files-vue'); +const { cleanup: cleanupVue, writeFiles: writeVueFiles, customizeFiles: customizeVueFiles } = require('./files-vue'); const writeCommonFiles = require('./files-common').writeFiles; const { clientI18nFiles } = require('../languages/files'); @@ -321,6 +321,8 @@ module.exports = class JHipsterClientGenerator extends BaseBlueprintGenerator { // Public API method used by the getter and also by Blueprints _writing() { return { + cleanupVue, + write() { if (this.skipClient) return; switch (this.clientFramework) { diff --git a/generators/client/templates/vue/package.json b/generators/client/templates/vue/package.json index 7c649317d55..1c0a6ac3d73 100644 --- a/generators/client/templates/vue/package.json +++ b/generators/client/templates/vue/package.json @@ -51,9 +51,7 @@ "jest-vue-preprocessor": "1.7.1", "merge-jsons-webpack-plugin": "1.0.21", "mini-css-extract-plugin": "2.4.2", - "node-notifier": "9.0.1", "numeral": "2.0.6", - "portfinder": "1.0.28", "postcss": "8.3.9", "postcss-import": "14.0.2", "postcss-loader": "6.1.1", diff --git a/generators/client/templates/vue/package.json.ejs b/generators/client/templates/vue/package.json.ejs index 9df3ec616ad..e90760789cc 100644 --- a/generators/client/templates/vue/package.json.ejs +++ b/generators/client/templates/vue/package.json.ejs @@ -105,9 +105,7 @@ "merge-jsons-webpack-plugin": "<%= dependabotPackageJson.devDependencies['merge-jsons-webpack-plugin'] %>", <%_ } _%> "mini-css-extract-plugin": "<%= dependabotPackageJson.devDependencies['mini-css-extract-plugin'] %>", - "node-notifier": "<%= dependabotPackageJson.devDependencies['node-notifier'] %>", "numeral": "<%= dependabotPackageJson.devDependencies['numeral'] %>", - "portfinder": "<%= dependabotPackageJson.devDependencies['portfinder'] %>", "postcss": "<%= dependabotPackageJson.devDependencies['postcss'] %>", "postcss-import": "<%= dependabotPackageJson.devDependencies['postcss-import'] %>", "postcss-loader": "<%= dependabotPackageJson.devDependencies['postcss-loader'] %>", @@ -187,13 +185,13 @@ "test-ci": "<%= clientPackageManager %> run lint && <%= clientPackageManager %> run jest:update --", "test:watch": "<%= clientPackageManager %> run jest -- --watch", "webapp:build": "<%= clientPackageManager %> run clean-www && <%= clientPackageManager %> run webapp:build:dev --", - "webapp:build:dev": "<%= clientPackageManager %> run webpack -- --config webpack/webpack.dev.js --progress=profile --env stats=minimal", - "webapp:build:prod": "<%= clientPackageManager %> run webpack -- --config webpack/webpack.prod.js --progress=profile --env stats=minimal", - "webapp:dev": "<%= clientPackageManager %> run webpack-dev-server -- --config webpack/webpack.dev.js --progress=profile --env stats=normal", + "webapp:build:dev": "<%= clientPackageManager %> run webpack -- --mode development --progress=profile --env stats=minimal", + "webapp:build:prod": "<%= clientPackageManager %> run webpack -- --mode production --progress=profile --env stats=minimal", + "webapp:dev": "<%= clientPackageManager %> run webpack-dev-server -- --mode development --progress=profile --env stats=normal", "webapp:prod": "<%= clientPackageManager %> run clean-www && <%= clientPackageManager %> run webapp:build:prod --", "webapp:test": "<%= clientPackageManager %> run test --", - "webpack-dev-server": "webpack serve", - "webpack": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js" + "webpack-dev-server": "webpack serve --config webpack/webpack.common.js", + "webpack": "webpack --config webpack/webpack.common.js" }, "jestSonar": { "reportPath": "<%= BUILD_DIR %>test-results/jest", diff --git a/generators/client/templates/vue/src/main/webapp/app/constants.ts.ejs b/generators/client/templates/vue/src/main/webapp/app/constants.ts.ejs index 096c681517d..cf3d9359e2e 100644 --- a/generators/client/templates/vue/src/main/webapp/app/constants.ts.ejs +++ b/generators/client/templates/vue/src/main/webapp/app/constants.ts.ejs @@ -1,11 +1,21 @@ -// These constants are injected via webpack environment variables. -// You can add more variables in webpack.common.js or in profile specific webpack..js files. -// If you change the values in the webpack config files, you need to re run webpack to update the application +<%# + Copyright 2013-2021 the original author or authors from the JHipster project. -export const VERSION = process.env.VERSION; -// export const DEBUG_INFO_ENABLED: boolean = !!process.env.DEBUG_INFO_ENABLED; -export const SERVER_API_URL = process.env.SERVER_API_URL; + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-%> // Errors export const PROBLEM_BASE_URL = 'https://www.jhipster.tech/problem'; export const EMAIL_ALREADY_USED_TYPE = `${PROBLEM_BASE_URL}/email-already-used`; diff --git a/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.component.ts.ejs b/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.component.ts.ejs index 68285ef260a..ee503920d97 100644 --- a/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.component.ts.ejs +++ b/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.component.ts.ejs @@ -1,5 +1,4 @@ import { Component, Inject, Vue } from 'vue-property-decorator'; -import { VERSION } from '@/constants'; import LoginService from '@/account/login.service'; import AccountService from '@/account/account.service'; <%_ if (enableTranslation) { _%> @@ -14,7 +13,7 @@ export default class JhiNavbar extends Vue { @Inject('translationService') private translationService: () => TranslationService; <%_ } %> @Inject('accountService') private accountService: () => AccountService; - public version = VERSION ? 'v' + VERSION : ''; + public version = 'v' + VERSION; private currentLanguage = this.$store.getters.currentLanguage; private languages: any = this.$store.getters.languages; private hasAnyAuthorityValue = false; diff --git a/generators/client/templates/vue/src/main/webapp/app/shared/config/axios-interceptor.ts.ejs b/generators/client/templates/vue/src/main/webapp/app/shared/config/axios-interceptor.ts.ejs index de1ac950d75..abcc26228f9 100644 --- a/generators/client/templates/vue/src/main/webapp/app/shared/config/axios-interceptor.ts.ejs +++ b/generators/client/templates/vue/src/main/webapp/app/shared/config/axios-interceptor.ts.ejs @@ -18,8 +18,6 @@ -%> import axios from 'axios'; -import {SERVER_API_URL} from "@/constants"; - const TIMEOUT = 1000000; const onRequestSuccess = config => { <%_ if (authenticationTypeJwt) { _%> diff --git a/generators/client/templates/vue/src/main/webapp/app/shims-vue.d.ts.ejs b/generators/client/templates/vue/src/main/webapp/app/shims-vue.d.ts.ejs index cd627558599..a2790490852 100644 --- a/generators/client/templates/vue/src/main/webapp/app/shims-vue.d.ts.ejs +++ b/generators/client/templates/vue/src/main/webapp/app/shims-vue.d.ts.ejs @@ -1,7 +1,31 @@ +<%# + Copyright 2013-2021 the original author or authors from the JHipster project. + + This file is part of the JHipster project, see https://www.jhipster.tech/ + for more information. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +-%> +// These constants are injected via webpack environment variables. +// You can add more variables in webpack.common.js or in profile specific webpack..js files. +// If you change the values in the webpack config files, you need to re run webpack to update the application + +declare const SERVER_API_URL: string; +declare const VERSION: string; <%_ if (enableTranslation) { _%> declare const I18N_HASH: string; - <%_ } _%> + declare module '*.vue' { import Vue from 'vue'; export default Vue; diff --git a/generators/client/templates/vue/src/test/javascript/jest.conf.js.ejs b/generators/client/templates/vue/src/test/javascript/jest.conf.js.ejs index 7e06fd7e1d6..3699f112ec0 100644 --- a/generators/client/templates/vue/src/test/javascript/jest.conf.js.ejs +++ b/generators/client/templates/vue/src/test/javascript/jest.conf.js.ejs @@ -1,3 +1,5 @@ +const config = require('../../../webpack/config'); + module.exports = { testEnvironment: 'jsdom', coverageDirectory: '/<%= BUILD_DIR %>test-results/', @@ -18,11 +20,13 @@ module.exports = { testMatch: ['/<%= CLIENT_TEST_SRC_DIR %>spec/**/@(*.)@(spec.ts)'], snapshotSerializers: ['/node_modules/jest-serializer-vue'], rootDir: '../../../', -<%_ if (enableTranslation) { _%> globals: { +<%_ if (enableTranslation) { _%> I18N_HASH: 'generated_hash', - }, <%_ } _%> + SERVER_API_URL: config.serverApiUrl, + VERSION: config.version, + }, coverageThreshold: { global: { statements: 80, diff --git a/generators/client/templates/vue/src/test/javascript/spec/app/shared/config/axios-interceptor.spec.ts.ejs b/generators/client/templates/vue/src/test/javascript/spec/app/shared/config/axios-interceptor.spec.ts.ejs index 75bee43b7d8..26c17975326 100644 --- a/generators/client/templates/vue/src/test/javascript/spec/app/shared/config/axios-interceptor.spec.ts.ejs +++ b/generators/client/templates/vue/src/test/javascript/spec/app/shared/config/axios-interceptor.spec.ts.ejs @@ -1,5 +1,4 @@ import * as setupAxiosConfig from '@/shared/config/axios-interceptor'; -import { SERVER_API_URL } from '@/constants'; import * as sinon from 'sinon'; import axios from 'axios'; import MockAdapter from "axios-mock-adapter"; diff --git a/generators/client/templates/vue/webpack/config.js.ejs b/generators/client/templates/vue/webpack/config.js.ejs new file mode 100644 index 00000000000..982a3c943bc --- /dev/null +++ b/generators/client/templates/vue/webpack/config.js.ejs @@ -0,0 +1,48 @@ +'use strict'; + +const path = require('path'); + +<%_ if (buildToolUnknown) { _%> +const packageJson = require('./../package.json'); +<%_ } _%> + +module.exports = { + serverApiUrl: '', +<%_ if (buildToolUnknown) { _%> + version: packageJson.version, +<%_ } else { _%> + // APP_VERSION is passed as an environment variable from the Gradle / Maven build tasks. + version: process.env.hasOwnProperty('APP_VERSION') ? process.env.APP_VERSION : 'UNKNOWN', +<%_ } _%> + + dev: { + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: 'source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +}; diff --git a/generators/client/templates/vue/webpack/dev.env.js.ejs b/generators/client/templates/vue/webpack/dev.env.js.ejs deleted file mode 100644 index f8af821a28b..00000000000 --- a/generators/client/templates/vue/webpack/dev.env.js.ejs +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; -const webpackMerge = require('webpack-merge').merge; -const prodEnv = require('./prod.env'); -<%_ if (buildToolUnknown) { _%> -const packageJson = require('./../package.json'); -<%_ } _%> - -module.exports = webpackMerge(prodEnv, { - NODE_ENV: '"development"', - SERVER_API_URL: '\'\'', -<%_ if (buildToolUnknown) { _%> - VERSION: `'${packageJson.version}'`, -<%_ } else { _%> - // APP_VERSION is passed as an environment variable from the Gradle / Maven build tasks. - VERSION: `'${process.env.hasOwnProperty('APP_VERSION') ? process.env.APP_VERSION : 'UNKNOWN'}'`, -<%_ } _%> -}); diff --git a/generators/client/templates/vue/webpack/env.js.ejs b/generators/client/templates/vue/webpack/env.js.ejs deleted file mode 100644 index 12e326d0fbd..00000000000 --- a/generators/client/templates/vue/webpack/env.js.ejs +++ /dev/null @@ -1,67 +0,0 @@ -'use strict'; -// Template version: 1.3.1 -// see http://vuejs-templates.github.io/webpack for documentation. - -const path = require('path'); - -module.exports = { - dev: { - // Paths - assetsSubDirectory: 'static', - assetsPublicPath: '/', - proxyTable: {}, - - // Various Dev Server settings - host: 'localhost', // can be overwritten by process.env.HOST - port: <%= serverPort %>, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined - autoOpenBrowser: false, - errorOverlay: true, - notifyOnErrors: true, - poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- - - /** - * Source Maps - */ - - // https://webpack.js.org/configuration/devtool/#development - devtool: 'cheap-module-source-map', - - // If you have problems debugging vue-files in devtools, - // set this to false - it *may* help - // https://vue-loader.vuejs.org/en/options.html#cachebusting - cacheBusting: true, - - cssSourceMap: true - }, - - build: { - // Template for index.html - index: path.resolve(__dirname, '../target/www/index.html'), - - // Paths - assetsRoot: path.resolve(__dirname, '../target'), - assetsSubDirectory: 'static', - assetsPublicPath: '/', - - /** - * Source Maps - */ - - productionSourceMap: true, - // https://webpack.js.org/configuration/devtool/#production - devtool: 'source-map', - - // Gzip off by default as many popular static hosts such as - // Surge or Netlify already gzip all static assets for you. - // Before setting to `true`, make sure to: - // npm install --save-dev compression-webpack-plugin - productionGzip: false, - productionGzipExtensions: ['js', 'css'], - - // Run the build command with an extra argument to - // View the bundle analyzer report after build finishes: - // `npm run build --report` - // Set to `true` or `false` to always turn it on or off - bundleAnalyzerReport: process.env.npm_config_report - } -}; diff --git a/generators/client/templates/vue/webpack/loader.conf.js.ejs b/generators/client/templates/vue/webpack/loader.conf.js.ejs deleted file mode 100644 index 667ee71c7a3..00000000000 --- a/generators/client/templates/vue/webpack/loader.conf.js.ejs +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; -const utils = require('./vue.utils'); -const config = require('./env'); -const isProduction = process.env.NODE_ENV === 'production'; -const sourceMapEnabled = isProduction ? config.build.productionSourceMap : config.dev.cssSourceMap; - -module.exports = { - loaders: utils.cssLoaders({ - sourceMap: sourceMapEnabled, - extract: isProduction - }), - cssSourceMap: sourceMapEnabled, - cacheBusting: config.dev.cacheBusting, - transformToRequire: { - video: ['src', 'poster'], - source: 'src', - img: 'src', - image: 'xlink:href' - } -}; diff --git a/generators/client/templates/vue/webpack/prod.env.js.ejs b/generators/client/templates/vue/webpack/prod.env.js.ejs deleted file mode 100644 index 84d54319f98..00000000000 --- a/generators/client/templates/vue/webpack/prod.env.js.ejs +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; -<%_ if (buildToolUnknown) { _%> -const packageJson = require('./../package.json'); -<%_ } _%> - -module.exports = { - NODE_ENV: '"production"', - SERVER_API_URL: '""', -<%_ if (buildToolUnknown) { _%> - VERSION: `'${packageJson.version}'`, -<%_ } else { _%> - // APP_VERSION is passed as an environment variable from the Gradle / Maven build tasks. - VERSION: `'${process.env.hasOwnProperty('APP_VERSION') ? process.env.APP_VERSION : 'UNKNOWN'}'`, -<%_ } _%> -}; diff --git a/generators/client/templates/vue/webpack/utils.js.ejs b/generators/client/templates/vue/webpack/utils.js.ejs deleted file mode 100644 index 20c19b2c6e2..00000000000 --- a/generators/client/templates/vue/webpack/utils.js.ejs +++ /dev/null @@ -1,30 +0,0 @@ -<%# - Copyright 2013-2021 the original author or authors from the JHipster project. - - This file is part of the JHipster project, see https://www.jhipster.tech/ - for more information. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. --%> -const path = require('path'); - -module.exports = { - root -}; - -const _root = path.resolve(__dirname, '..'); - -function root(args) { - args = Array.prototype.slice.call(arguments, 0); - return path.join.apply(path, [_root].concat(args)); -} diff --git a/generators/client/templates/vue/webpack/vue.utils.js.ejs b/generators/client/templates/vue/webpack/vue.utils.js.ejs index 396e616f153..a906c1f5f31 100644 --- a/generators/client/templates/vue/webpack/vue.utils.js.ejs +++ b/generators/client/templates/vue/webpack/vue.utils.js.ejs @@ -1,17 +1,14 @@ 'use strict'; const path = require('path'); -const config = require('./env'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const packageConfig = require('../package.json'); const sass = require('sass'); -exports.assetsPath = function(_path) { - const assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory; +const packageConfig = require('../package.json'); +const config = require('./config'); - return path.posix.join(assetsSubDirectory, _path); -}; +const sourceMapEnabled = production => production ? config.build.productionSourceMap : config.dev.cssSourceMap; -exports.cssLoaders = function(options) { +const cssLoaders = options => { options = options || {}; const cssLoader = { @@ -60,9 +57,9 @@ exports.cssLoaders = function(options) { }; // Generate loaders for standalone style files (outside of .vue) -exports.styleLoaders = function(options) { +const styleLoaders = options => { const output = []; - const loaders = exports.cssLoaders(options); + const loaders = cssLoaders(options); for (const extension in loaders) { const loader = loaders[extension]; @@ -75,20 +72,23 @@ exports.styleLoaders = function(options) { return output; }; -exports.createNotifierCallback = () => { - const notifier = require('node-notifier'); - - return (severity, errors) => { - if (severity !== 'error') return; - - const error = errors[0]; - const filename = error.file && error.file.split('!').pop(); +const vueLoaderConfig = production => ({ + loaders: cssLoaders({ + sourceMap: sourceMapEnabled(production), + extract: production + }), + cssSourceMap: sourceMapEnabled(production), + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +}); - notifier.notify({ - title: packageConfig.name, - message: severity + ': ' + error.name, - subtitle: filename || '', - icon: path.join(__dirname, 'logo.png') - }); - }; -}; +module.exports = { + cssLoaders, + styleLoaders, + vueLoaderConfig, +} diff --git a/generators/client/templates/vue/webpack/webpack.common.js.ejs b/generators/client/templates/vue/webpack/webpack.common.js.ejs index 939d69dce8f..f44219c644f 100644 --- a/generators/client/templates/vue/webpack/webpack.common.js.ejs +++ b/generators/client/templates/vue/webpack/webpack.common.js.ejs @@ -7,151 +7,163 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const { hashElement } = require('folder-hash'); const MergeJsonWebpackPlugin = require('merge-jsons-webpack-plugin'); <%_ } _%> -const { DefinePlugin } = require('webpack'); -const vueLoaderConfig = require('./loader.conf'); -function resolve(dir) { +const { DefinePlugin, EnvironmentPlugin } = require('webpack'); +const { vueLoaderConfig } = require('./vue.utils'); +const config = require('./config'); + +function resolve(dir = '') { return path.join(__dirname, '..', dir); } -module.exports = async env => { +module.exports = async (env, options) => { + const development = options.mode === 'development'; <%_ if (enableTranslation) { _%> - const languagesHash = await hashElement(path.resolve(__dirname, '../<%= MAIN_SRC_DIR %>i18n'), { + const languagesHash = await hashElement(resolve('<%= MAIN_SRC_DIR %>i18n'), { algo: 'md5', encoding: 'hex', files: { include: ['*.json'] }, }); <%_ } _%> - return merge( -{ - mode: 'development', - context: path.resolve(__dirname, '../'), - entry: { - app: './<%= CLIENT_MAIN_SRC_DIR %>app/main.ts' - }, - resolve: { - extensions: ['.ts', '.js', '.vue', '.json'], - alias: { - vue$: 'vue/dist/vue.esm.js', - '@': resolve('<%= CLIENT_MAIN_SRC_DIR %>app') - }, - fallback: { - // prevent webpack from injecting useless setImmediate polyfill because Vue - // source contains it (although only uses it if it's native). - setImmediate: false, - // prevent webpack from injecting mocks to Node native modules - // that does not make sense for the client - dgram: 'empty', - fs: 'empty', - net: 'empty', - tls: 'empty', - child_process: 'empty', - }, - }, - cache: { - // 1. Set cache type to filesystem - type: 'filesystem', - cacheDirectory: path.resolve(__dirname, '../<%= buildDir %>webpack'), - buildDependencies: { - // 2. Add your config as buildDependency to get cache invalidation on config change - config: [ - __filename, - path.resolve(__dirname, `webpack.${env.env == 'development' ? 'dev' : 'prod'}.js`), - path.resolve(__dirname, 'utils.js'), - path.resolve(__dirname, '../.postcssrc.js'), - path.resolve(__dirname, '../tsconfig.json') - ], - }, - }, - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: vueLoaderConfig + { + mode: options.mode, + context: resolve(), + entry: { + app: './<%= CLIENT_MAIN_SRC_DIR %>app/main.ts' + }, + output: { + path: resolve('<%= DIST_DIR %>'), }, - { - test: /\.ts$/, - use: [ + resolve: { + extensions: ['.ts', '.js', '.vue', '.json'], + alias: { + vue$: 'vue/dist/vue.esm.js', + '@': resolve('<%= CLIENT_MAIN_SRC_DIR %>app') + }, + fallback: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty', + }, + }, + cache: { + // 1. Set cache type to filesystem + type: 'filesystem', + cacheDirectory: resolve('<%= buildDir %>webpack'), + buildDependencies: { + // 2. Add your config as buildDependency to get cache invalidation on config change + config: [ + __filename, + path.resolve(__dirname, 'config.js'), + path.resolve(__dirname, 'vue.utils.js'), + path.resolve(__dirname, `webpack.${development ? 'dev' : 'prod'}.js`), + path.resolve(__dirname, '../.postcssrc.js'), + path.resolve(__dirname, '../tsconfig.json') + ], + }, + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig(!development) + }, + { + test: /\.ts$/, + use: [ + { + loader: 'ts-loader', + options: { + appendTsSuffixTo: ['\\.vue$'], + happyPackMode: true, + transpileOnly: true + } + } + ], + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: 'content/[hash].[ext]', + publicPath: "../" + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: 'content/[hash].[ext]', + publicPath: "../" + } + }, { - loader: 'ts-loader', + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', options: { - appendTsSuffixTo: ['\\.vue$'], - happyPackMode: true, - transpileOnly: true + limit: 10000, + name: 'content/[hash].[ext]', + publicPath: "../" } } - ], - include: [resolve('src'), resolve('test')] - }, - { - test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, - loader: 'url-loader', - options: { - limit: 10000, - name: 'content/[hash].[ext]', - publicPath: "../" - } - }, - { - test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, - loader: 'url-loader', - options: { - limit: 10000, - name: 'content/[hash].[ext]', - publicPath: "../" - } + ] }, - { - test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, - loader: 'url-loader', - options: { - limit: 10000, - name: 'content/[hash].[ext]', - publicPath: "../" - } - } - ] - }, - plugins: [ - new DefinePlugin({ + plugins: [ + new EnvironmentPlugin({ + // Required by vuelidate https://github.com/vuelidate/vuelidate/issues/365 + BUILD: 'web', + }), + new DefinePlugin({ <%_ if (enableTranslation) { _%> - I18N_HASH: JSON.stringify(languagesHash.hash), + I18N_HASH: JSON.stringify(languagesHash.hash), <%_ } _%> - 'process.env': require(env.env == 'development' ? './dev.env' : './prod.env'), - }), - new VueLoaderPlugin(), - new CopyWebpackPlugin({ - patterns: [ - { - context: './node_modules/swagger-ui-dist/', - from: '*.{js,css,html,png}', - to: 'swagger-ui/', - globOptions: { ignore: ['**/index.html'] }, - }, - { from: './node_modules/axios/dist/axios.min.js', to: 'swagger-ui/' }, - { from: './<%= CLIENT_MAIN_SRC_DIR %>swagger-ui/', to: 'swagger-ui/' }, - { from: './<%= CLIENT_MAIN_SRC_DIR %>content/', to: 'content/' }, - { from: './<%= CLIENT_MAIN_SRC_DIR %>favicon.ico', to: 'favicon.ico' }, - { - from: './<%= CLIENT_MAIN_SRC_DIR %>manifest.webapp', - to: 'manifest.webapp', - }, - // jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array - { from: './<%= CLIENT_MAIN_SRC_DIR %>robots.txt', to: 'robots.txt' }, + VERSION: JSON.stringify(config.version), + SERVER_API_URL: JSON.stringify(config.serverApiUrl), + }), + new VueLoaderPlugin(), + new CopyWebpackPlugin({ + patterns: [ + { + context: './node_modules/swagger-ui-dist/', + from: '*.{js,css,html,png}', + to: 'swagger-ui/', + globOptions: { ignore: ['**/index.html'] }, + }, + { from: './node_modules/axios/dist/axios.min.js', to: 'swagger-ui/' }, + { from: './<%= CLIENT_MAIN_SRC_DIR %>swagger-ui/', to: 'swagger-ui/' }, + { from: './<%= CLIENT_MAIN_SRC_DIR %>content/', to: 'content/' }, + { from: './<%= CLIENT_MAIN_SRC_DIR %>favicon.ico', to: 'favicon.ico' }, + { + from: './<%= CLIENT_MAIN_SRC_DIR %>manifest.webapp', + to: 'manifest.webapp', + }, + // jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array + { from: './<%= CLIENT_MAIN_SRC_DIR %>robots.txt', to: 'robots.txt' }, + ] + })<% if (enableTranslation) { %>, + new MergeJsonWebpackPlugin({ + output: { + groupBy: [ + // jhipster-needle-i18n-language-webpack - JHipster will add/remove languages in this array + ] + } + })<% } %> ] - })<% if (enableTranslation) { %>, - new MergeJsonWebpackPlugin({ - output: { - groupBy: [ - // jhipster-needle-i18n-language-webpack - JHipster will add/remove languages in this array - ] - } - })<% } %> - ] -} -// jhipster-needle-add-webpack-config - JHipster will add custom config -); + }, + await require(`./webpack.${development ? 'dev' : 'prod'}`)(env, options) + // jhipster-needle-add-webpack-config - JHipster will add custom config + ); }; diff --git a/generators/client/templates/vue/webpack/webpack.dev.js.ejs b/generators/client/templates/vue/webpack/webpack.dev.js.ejs index 5b21f1ae184..f48193eb7a9 100644 --- a/generators/client/templates/vue/webpack/webpack.dev.js.ejs +++ b/generators/client/templates/vue/webpack/webpack.dev.js.ejs @@ -18,21 +18,16 @@ -%> 'use strict'; const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); -const portfinder = require('portfinder'); +const path = require('path'); const webpack = require('webpack'); -const { merge: webpackMerge } = require('webpack-merge'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -const utils = require('./vue.utils'); -const config = require('./env'); -const commonConfig = require('./webpack.common'); -const jhiUtils = require('./utils.js'); -const MODE = 'development'; +const { styleLoaders } = require('./vue.utils'); +const config = require('./config'); -module.exports = async env => webpackMerge(await commonConfig({ env: MODE }), { - mode: MODE, +module.exports = (env, options) => ({ module: { - rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + rules: styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, // cheap-module-eval-source-map is faster for development devtool: config.dev.devtool, @@ -41,7 +36,6 @@ module.exports = async env => webpackMerge(await commonConfig({ env: MODE }), { main: './<%= MAIN_SRC_DIR %>app/main' }, output: { - path: jhiUtils.root('<%= DIST_DIR %>'), filename: 'app/[contenthash].bundle.js', chunkFilename: 'app/[id].chunk.js' }, diff --git a/generators/client/templates/vue/webpack/webpack.prod.js.ejs b/generators/client/templates/vue/webpack/webpack.prod.js.ejs index cbb6f1dc576..761eef66ef5 100644 --- a/generators/client/templates/vue/webpack/webpack.prod.js.ejs +++ b/generators/client/templates/vue/webpack/webpack.prod.js.ejs @@ -18,7 +18,6 @@ -%> 'use strict'; const webpack = require('webpack'); -const webpackMerge = require('webpack-merge').merge; const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); @@ -26,17 +25,12 @@ const WorkboxPlugin = require('workbox-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -const utils = require('./vue.utils'); -const config = require('./env'); -const baseWebpackConfig = require('./webpack.common'); -const jhiUtils = require('./utils.js'); - -const MODE = 'production'; +const { styleLoaders } = require('./vue.utils'); +const config = require('./config'); const webpackConfig = { - mode: MODE, module: { - rules: utils.styleLoaders({ + rules: styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true @@ -48,7 +42,6 @@ const webpackConfig = { main: './<%= MAIN_SRC_DIR %>app/main' }, output: { - path: jhiUtils.root('<%= DIST_DIR %>'), filename: 'app/[name].[contenthash].bundle.js', chunkFilename: 'app/[id].[chunkhash].chunk.js' }, @@ -170,4 +163,4 @@ if (config.build.bundleAnalyzerReport) { webpackConfig.plugins.push(new BundleAnalyzerPlugin()); } -module.exports = async () => webpackMerge(await baseWebpackConfig({ env: MODE }), webpackConfig); +module.exports = async () => webpackConfig; diff --git a/test/vue.spec.js b/test/vue.spec.js index 96838204c98..a78c768685d 100644 --- a/test/vue.spec.js +++ b/test/vue.spec.js @@ -215,8 +215,7 @@ const expectedFiles = { ], webpack: [ - `${CLIENT_WEBPACK_DIR}/loader.conf.js`, - `${CLIENT_WEBPACK_DIR}/utils.js`, + `${CLIENT_WEBPACK_DIR}/config.js`, `${CLIENT_WEBPACK_DIR}/vue.utils.js`, `${CLIENT_WEBPACK_DIR}/webpack.common.js`, `${CLIENT_WEBPACK_DIR}/webpack.dev.js`,