diff --git a/src/plugins/index.js b/src/plugins/index.js index 47a45b6..9e6d078 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -1,7 +1,9 @@ const ProjextWebpackBundleRunner = require('./bundleRunner'); const ProjextWebpackOpenDevServer = require('./openDevServer'); +const ProjextWebpackRuntimeDefinitions = require('./runtimeDefinitions'); module.exports = { ProjextWebpackBundleRunner, ProjextWebpackOpenDevServer, + ProjextWebpackRuntimeDefinitions, }; diff --git a/src/plugins/runtimeDefinitions/index.js b/src/plugins/runtimeDefinitions/index.js new file mode 100644 index 0000000..f485a69 --- /dev/null +++ b/src/plugins/runtimeDefinitions/index.js @@ -0,0 +1,137 @@ +const ObjectUtils = require('wootils/shared/objectUtils'); +const { DefinePlugin } = require('webpack'); +/** + * This is a webpack plugin that works with `webpack.DefinePlugin` in order to reload all + * definitions when the bundle changes. + */ +class ProjextWebpackRuntimeDefinitions { + /** + * @param {Array} files The list of files that need to + * change in order to reload + * the definitions. + * @param {Function():Object} definitionsFn When this function is called, + * it should return the object + * with the definitions. + * @param {ProjextWebpackRuntimeDefinitionsOptions} [options={}] The options to customize the + * plugin instance. + * @throws {Error} If `files` is not an Array. + * @throws {Error} If `files` is empty. + * @throws {Error} If `definitionsFn` is not a function. + */ + constructor(files, definitionsFn, options = {}) { + if (!Array.isArray(files) || !files.length) { + throw new Error('You need to provide a valid files list'); + } + + if (typeof definitionsFn !== 'function') { + throw new Error('You need to provide a valid definitions function'); + } + + /** + * The list of files that need to change in order to reload the definitions. + * @type {Array} + * @access protected + * @ignore + */ + this._files = files; + /** + * The function that will generate the definitions. + * @type {Function():Object} + * @access protected + * @ignore + */ + this._definitionsFn = definitionsFn; + /** + * The options to customize the plugin instance. + * @type {ProjextWebpackRuntimeDefinitionsOptions} + * @access protected + * @ignore + */ + this._options = ObjectUtils.merge( + { + name: 'projext-webpack-plugin-runtime-definitions', + }, + options + ); + /** + * This is where the plugin will "refresh" the definitions when the bundle changes. + * @type {Object} + * @access protected + * @ignore + */ + this._values = {}; + } + /** + * Get the options that customize the plugin instance. + * @return {ProjextWebpackRuntimeDefinitionsOptions} + */ + getOptions() { + return this._options; + } + /** + * This is called by webpack when the plugin is being processed. The method will create a new + * instance of `webpack.DefinePlugin` and set all the values as "runtime values", so they'll + * get evaluated every time the bundle is generated. + * The method will also tap into the `compile` hook, so this plugin can refresh the values (by + * calling the `definitionFn`) when the bundle is about to be generated. + * @param {Object} compiler The compiler information provided by webpack. + */ + apply(compiler) { + const plugin = new DefinePlugin(this._getDefinePluginSettings()); + plugin.apply(compiler); + compiler.hooks.compile.tap( + this._options.name, + this._onCompilationStarts.bind(this) + ); + } + /** + * Reloads the saved values on the instance by calling the `definitionsFn`. + * @access protected + * @ignore + */ + _reloadValues() { + this._values = this._definitionsFn(); + return this._values; + } + /** + * Generates the settings for `webpack.DefinePlugin`. It basically creates a "runtime value" for + * each of the definitions keys and sets a function that will call this instance. + * @return {Object} + * @access protected + * @ignore + */ + _getDefinePluginSettings() { + const keys = Object.keys(this._reloadValues()); + return keys.reduce( + (settings, key) => Object.assign({}, settings, { + [key]: DefinePlugin.runtimeValue( + () => this._getValue(key), + this._files + ), + }), + {} + ); + } + /** + * Get a single value from a definition already loaded. + * @param {string} key The definition key. + * @return {string} + * @access protected + * @ignore + */ + _getValue(key) { + return this._values[key]; + } + /** + * This is called by webpack when the bundle compilation starts. The method just reloads the + * definition values on the instance so they'll be available when `webpack.DefinePlugin` tries + * to access them. + * @access protected + * @ignore + */ + _onCompilationStarts() { + this._reloadValues(); + } +} + +module.exports = ProjextWebpackRuntimeDefinitions; diff --git a/src/services/building/configuration.js b/src/services/building/configuration.js index d905e9c..ae37f36 100644 --- a/src/services/building/configuration.js +++ b/src/services/building/configuration.js @@ -96,13 +96,8 @@ class WebpackConfiguration { output.jsChunks = this._generateChunkName(output.js); } - const definitions = this._getDefinitions(target, buildType); - const additionalWatch = []; - if (target.is.browser && target.configuration && target.configuration.enabled) { - const browserConfig = this.targets.getBrowserTargetConfiguration(target); - definitions[target.configuration.defineOn] = JSON.stringify(browserConfig.configuration); - additionalWatch.push(...browserConfig.files); - } + const definitions = this._getDefinitionsGenerator(target, buildType); + const additionalWatch = this._getBrowserTargetConfigurationDefinitions(target).files; const params = { target, @@ -134,16 +129,29 @@ class WebpackConfiguration { return config; } /** - * Get a dictionary of definitions that will be replaced on the generated bundle. This is done - * using the `webpack.DefinePlugin` plugin. - * @param {Target} target The target information. - * @param {string} env The `NODE_ENV` to define. + * Generates a function that when called will return a dictionary with definitions that will be + * replaced on the bundle. + * @param {Target} target The target information. + * @param {string} buildType The intended build type: `production` or `development`. + * @return {Function():Object} + * @access protected + * @ignore + */ + _getDefinitionsGenerator(target, buildType) { + return () => this._getTargetDefinitions(target, buildType); + } + /** + * Generates a dictionary with definitions that will be replaced on the bundle. These + * definitions are things like `process.env.NODE_ENV`, the bundle version, a browser target + * configuration, etc. + * @param {Target} target The target information. + * @param {string} buildType The intended build type: `production` or `development`. * @return {Object} * @access protected * @ignore */ - _getDefinitions(target, env) { - const targetVariables = this.targets.loadTargetDotEnvFile(target, env); + _getTargetDefinitions(target, buildType) { + const targetVariables = this.targets.loadTargetDotEnvFile(target, buildType); const definitions = Object.keys(targetVariables).reduce( (current, variableName) => Object.assign({}, current, { [`process.env.${variableName}`]: JSON.stringify(targetVariables[variableName]), @@ -151,12 +159,48 @@ class WebpackConfiguration { {} ); - definitions['process.env.NODE_ENV'] = `'${env}'`; + definitions['process.env.NODE_ENV'] = `'${buildType}'`; definitions[this.buildVersion.getDefinitionVariable()] = JSON.stringify( this.buildVersion.getVersion() ); - return definitions; + return Object.assign( + {}, + definitions, + this._getBrowserTargetConfigurationDefinitions(target).definitions + ); + } + /** + * This is a wrapper on top of {@link Targets#getBrowserTargetConfiguration} so no matter the + * type of target it recevies, or if the feature is disabled, it will always return the same + * signature. + * It also takes care of formatting the configuration on a "definitions object" so it can be + * added to the rest of the targets definitions. + * @param {Target} target The target information. + * @return {Object} + * @property {Object} definitions A dictionary with + * @property {Array} files The list of files involved on the configuration creation. + * @access protected + * @ignore + */ + _getBrowserTargetConfigurationDefinitions(target) { + let result; + if (target.is.browser && target.configuration && target.configuration.enabled) { + const parsed = this.targets.getBrowserTargetConfiguration(target); + result = { + definitions: { + [target.configuration.defineOn]: JSON.stringify(parsed.configuration), + }, + files: parsed.files, + }; + } else { + result = { + definitions: {}, + files: [], + }; + } + + return result; } /** * In case the target is a library, this method will be called in order to get the extra output diff --git a/src/services/configurations/browserDevelopmentConfiguration.js b/src/services/configurations/browserDevelopmentConfiguration.js index 3b2d337..e092225 100644 --- a/src/services/configurations/browserDevelopmentConfiguration.js +++ b/src/services/configurations/browserDevelopmentConfiguration.js @@ -1,4 +1,5 @@ -const extend = require('extend'); +const path = require('path'); +const ObjectUtils = require('wootils/shared/objectUtils'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); @@ -7,13 +8,15 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); const { NoEmitOnErrorsPlugin, - DefinePlugin, HotModuleReplacementPlugin, NamedModulesPlugin, } = require('webpack'); const { provider } = require('jimple'); const ConfigurationFile = require('../../abstracts/configurationFile'); -const { ProjextWebpackOpenDevServer } = require('../../plugins'); +const { + ProjextWebpackOpenDevServer, + ProjextWebpackRuntimeDefinitions, +} = require('../../plugins'); /** * Creates the specifics of a Webpack configuration for a browser target development build. * @extends {ConfigurationFile} @@ -99,7 +102,7 @@ class WebpackBrowserDevelopmentConfiguration extends ConfigurationFile { } = params; // Define the basic stuff: entry, output and mode. const config = { - entry: extend(true, {}, entry), + entry: ObjectUtils.copy(entry), output: { path: `./${target.folders.build}`, filename: output.js, @@ -129,7 +132,13 @@ class WebpackBrowserDevelopmentConfiguration extends ConfigurationFile { // To avoid pushing assets with errors. new NoEmitOnErrorsPlugin(), // To add the _'browser env variables'_. - new DefinePlugin(definitions), + new ProjextWebpackRuntimeDefinitions( + Object.keys(entry).reduce( + (current, key) => [...current, ...entry[key].filter((file) => path.isAbsolute(file))], + [] + ), + definitions + ), // To optimize the SCSS and remove repeated declarations. new OptimizeCssAssetsPlugin(), // Copy the files the target specified on its settings. @@ -255,7 +264,7 @@ class WebpackBrowserDevelopmentConfiguration extends ConfigurationFile { */ _normalizeTargetDevServerSettings(target) { // Get a new copy of the config to work with. - const config = extend(true, {}, target.devServer); + const config = ObjectUtils.copy(target.devServer); /** * Set a flag to know if at least one SSL file was sent. * This flag is also used when reading the `proxied` settings to determine the default diff --git a/src/services/configurations/browserProductionConfiguration.js b/src/services/configurations/browserProductionConfiguration.js index c2b1a86..ffb91b0 100644 --- a/src/services/configurations/browserProductionConfiguration.js +++ b/src/services/configurations/browserProductionConfiguration.js @@ -1,3 +1,4 @@ +const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); const CompressionPlugin = require('compression-webpack-plugin'); @@ -6,9 +7,9 @@ const TerserPlugin = require('terser-webpack-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); -const { DefinePlugin } = require('webpack'); const { provider } = require('jimple'); const ConfigurationFile = require('../../abstracts/configurationFile'); +const { ProjextWebpackRuntimeDefinitions } = require('../../plugins'); /** * Creates the specifics of a Webpack configuration for a browser target production build. * @extends {ConfigurationFile} @@ -122,7 +123,13 @@ class WebpackBrowserProductionConfiguration extends ConfigurationFile { ] ), // To add the _'browser env variables'_. - new DefinePlugin(definitions), + new ProjextWebpackRuntimeDefinitions( + Object.keys(entry).reduce( + (current, key) => [...current, ...entry[key].filter((file) => path.isAbsolute(file))], + [] + ), + definitions + ), // To optimize the SCSS and remove repeated declarations. new OptimizeCssAssetsPlugin(), // To compress the emitted assets using gzip, if the target is not a library. diff --git a/src/typedef.js b/src/typedef.js index 6c932f8..e447a44 100644 --- a/src/typedef.js +++ b/src/typedef.js @@ -195,8 +195,8 @@ * @property {WebpackConfigurationTargetOutput} output * A dictionary with the filenames formats and paths of the different files the bundle can * generate. - * @property {Object} definitions - * A dictionary of defined variables that will be replaced on the bundled code. + * @property {Function():Object} definitions + * A function that generates a dictionary of variables that will be replaced on the bundled code. * @property {string} buildType * The intended built type: `development` or `production`. * @property {Array} copy @@ -279,3 +279,10 @@ * Its default value is `projext-webpack-plugin-open-dev-server`. * @property {?Logger} logger A custom logger to output the plugin's information messages. */ + +/** + * @typedef {Object} ProjextWebpackRuntimeDefinitionsOptions + * @property {?string} name The _"instance name"_, used to register the listeners on the + * webpack event hooks. Its default value is + * `projext-webpack-plugin-runtime-definitions`. + */ diff --git a/tests/mocks/webpack.mock.js b/tests/mocks/webpack.mock.js index 0459150..29ee8a5 100644 --- a/tests/mocks/webpack.mock.js +++ b/tests/mocks/webpack.mock.js @@ -1,6 +1,8 @@ const mocks = { noEmitOnErrorsPlugin: jest.fn(), definePlugin: jest.fn(), + definePluginApply: jest.fn(), + definePluginRuntimeValue: jest.fn(), hotModuleReplacementPlugin: jest.fn(), namedModulesPlugin: jest.fn(), }; @@ -13,10 +15,19 @@ class NoEmitOnErrorsPluginMock { } class DefinePluginMock { + static runtimeValue(...args) { + return mocks.definePluginRuntimeValue(...args); + } + constructor(...args) { this.constructorMock = mocks.definePlugin; + this.applyMock = mocks.definePluginApply; this.constructorMock(...args); } + + apply(...args) { + this.applyMock(...args); + } } class HotModuleReplacementPluginMock { @@ -50,6 +61,8 @@ module.exports.NoEmitOnErrorsPlugin = NoEmitOnErrorsPluginMock; module.exports.NoEmitOnErrorsPluginMock = mocks.noEmitOnErrorsPlugin; module.exports.DefinePlugin = DefinePluginMock; module.exports.DefinePluginMock = mocks.definePlugin; +module.exports.DefinePluginApplyMock = mocks.definePluginApply; +module.exports.DefinePluginRuntimeValueMock = mocks.definePluginRuntimeValue; module.exports.HotModuleReplacementPlugin = HotModuleReplacementPluginMock; module.exports.HotModuleReplacementPluginMock = mocks.hotModuleReplacementPlugin; module.exports.NamedModulesPlugin = NamedModulesPluginMock; diff --git a/tests/plugins/runtimeDefinitions/index.test.js b/tests/plugins/runtimeDefinitions/index.test.js new file mode 100644 index 0000000..55834c5 --- /dev/null +++ b/tests/plugins/runtimeDefinitions/index.test.js @@ -0,0 +1,113 @@ +const webpackMock = require('/tests/mocks/webpack.mock'); + +jest.unmock('/src/plugins/runtimeDefinitions'); +jest.mock('webpack', () => webpackMock); + +const ProjextWebpackRuntimeDefinitions = require('/src/plugins/runtimeDefinitions'); + +describe('plugins:runtimeDefinitions', () => { + beforeEach(() => { + webpackMock.reset(); + }); + + it('should be instantiated', () => { + // Given + let sut = null; + let result = null; + // When + sut = new ProjextWebpackRuntimeDefinitions(['file'], () => {}); + result = sut.getOptions(); + // Then + expect(sut).toBeInstanceOf(ProjextWebpackRuntimeDefinitions); + expect(result).toEqual({ + name: 'projext-webpack-plugin-runtime-definitions', + }); + }); + + it('should throw error when instantiated without a files list', () => { + // Given/When/Then + expect(() => new ProjextWebpackRuntimeDefinitions()) + .toThrow(/You need to provide a valid files list/i); + }); + + it('should throw error when instantiated without a definitions function', () => { + // Given/When/Then + expect(() => new ProjextWebpackRuntimeDefinitions(['file'])) + .toThrow(/You need to provide a valid definitions function/i); + }); + + it('should be instantiated with custom option', () => { + // Given + const options = { + name: 'custom', + }; + let sut = null; + let result = null; + // When + sut = new ProjextWebpackRuntimeDefinitions(['file'], () => {}, options); + result = sut.getOptions(); + // Then + expect(sut).toBeInstanceOf(ProjextWebpackRuntimeDefinitions); + expect(result).toEqual(options); + }); + + it('should create the DefinePlugin and hook to the compilation', () => { + // Given + webpackMock.DefinePluginRuntimeValueMock.mockImplementationOnce((fn) => fn()); + const files = ['file']; + const definitionVarName = 'ROSARIO'; + const definitionVarValue = 'Charito!'; + const definitionFn = jest.fn(() => ({ + [definitionVarName]: definitionVarValue, + })); + const compiler = { + hooks: { + compile: { + tap: jest.fn(), + }, + }, + }; + let sut = null; + // When + sut = new ProjextWebpackRuntimeDefinitions(files, definitionFn); + sut.apply(compiler); + // Then + expect(definitionFn).toHaveBeenCalledTimes(1); + expect(webpackMock.DefinePluginRuntimeValueMock).toHaveBeenCalledTimes(1); + expect(webpackMock.DefinePluginRuntimeValueMock).toHaveBeenCalledWith( + expect.any(Function), + files + ); + expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); + expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith({ + [definitionVarName]: definitionVarValue, + }); + expect(compiler.hooks.compile.tap).toHaveBeenCalledTimes(1); + expect(compiler.hooks.compile.tap).toHaveBeenCalledWith( + sut.getOptions().name, + expect.any(Function) + ); + }); + + it('should refresh the definitions when the bundle changes', () => { + // Given + webpackMock.DefinePluginRuntimeValueMock.mockImplementationOnce((fn) => fn()); + const definitionFn = jest.fn(() => ({})); + const compiler = { + hooks: { + compile: { + tap: jest.fn(), + }, + }, + }; + let sut = null; + let onCompile = null; + // When + sut = new ProjextWebpackRuntimeDefinitions(['file'], definitionFn); + sut.apply(compiler); + [[, onCompile]] = compiler.hooks.compile.tap.mock.calls; + onCompile(); + // Then + expect(definitionFn).toHaveBeenCalledTimes(2); + }); +}); diff --git a/tests/services/building/configuration.test.js b/tests/services/building/configuration.test.js index 55ee65d..19e93b0 100644 --- a/tests/services/building/configuration.test.js +++ b/tests/services/building/configuration.test.js @@ -171,6 +171,8 @@ describe('services/building:configuration', () => { const webpackPluginInfo = 'webpackPluginInfo'; let sut = null; let result = null; + let definitionsGenerator = null; + let generatedDefinitions = null; // When sut = new WebpackConfiguration( buildVersion, @@ -182,8 +184,15 @@ describe('services/building:configuration', () => { webpackPluginInfo ); result = sut.getConfig(target, buildType); + [[{ definitions: definitionsGenerator }]] = targetConfig.getConfig.mock.calls; + generatedDefinitions = definitionsGenerator(); // Then expect(result).toEqual(config); + expect(generatedDefinitions).toEqual({ + [`process.env.${envVarName}`]: `"${envVarValue}"`, + 'process.env.NODE_ENV': `'${buildType}'`, + [versionVariable]: `"${version}"`, + }); expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(1); expect(buildVersion.getVersion).toHaveBeenCalledTimes(1); expect(targetsFileRules.getRulesForTarget).toHaveBeenCalledTimes(1); @@ -206,11 +215,7 @@ describe('services/building:configuration', () => { entry: { [target.name]: [path.join(target.paths.source, target.entry[buildType])], }, - definitions: { - [`process.env.${envVarName}`]: `"${envVarValue}"`, - 'process.env.NODE_ENV': `'${buildType}'`, - [versionVariable]: `"${version}"`, - }, + definitions: expect.any(Function), output: Object.assign({}, target.output[buildType], { jsChunks: target.output[buildType].js.replace(/\.js$/, '.[name].js'), }), @@ -298,8 +303,8 @@ describe('services/building:configuration', () => { result = sut.getConfig(target, buildType); // Then expect(result).toEqual(config); - expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(1); - expect(buildVersion.getVersion).toHaveBeenCalledTimes(1); + expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(0); + expect(buildVersion.getVersion).toHaveBeenCalledTimes(0); expect(targetsFileRules.getRulesForTarget).toHaveBeenCalledTimes(1); expect(targetsFileRules.getRulesForTarget).toHaveBeenCalledWith(target); expect(targetConfiguration).toHaveBeenCalledTimes(['global', 'byBuildType'].length); @@ -311,8 +316,7 @@ describe('services/building:configuration', () => { `webpack/${target.name}.${buildType}.config.js`, targetConfig ); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(1); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledWith(target, buildType); + expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(0); expect(targetConfig.getConfig).toHaveBeenCalledTimes(1); expect(targetConfig.getConfig).toHaveBeenCalledWith({ target, @@ -320,10 +324,7 @@ describe('services/building:configuration', () => { entry: { [target.name]: [path.join(target.paths.source, target.entry[buildType])], }, - definitions: { - 'process.env.NODE_ENV': `'${buildType}'`, - [versionVariable]: `"${version}"`, - }, + definitions: expect.any(Function), output: Object.assign({}, target.output[buildType], { jsChunks: target.output[buildType].js.replace(/\.js$/, '.[name].js'), }), @@ -415,8 +416,8 @@ describe('services/building:configuration', () => { result = sut.getConfig(target, buildType); // Then expect(result).toEqual(config); - expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(1); - expect(buildVersion.getVersion).toHaveBeenCalledTimes(1); + expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(0); + expect(buildVersion.getVersion).toHaveBeenCalledTimes(0); expect(targetConfiguration).toHaveBeenCalledTimes(['global', 'byBuildType'].length); expect(targetConfiguration).toHaveBeenCalledWith( `webpack/${target.name}.config.js`, @@ -426,8 +427,7 @@ describe('services/building:configuration', () => { `webpack/${target.name}.${buildType}.config.js`, targetConfig ); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(1); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledWith(target, buildType); + expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(0); expect(targetConfig.getConfig).toHaveBeenCalledTimes(1); expect(targetConfig.getConfig).toHaveBeenCalledWith({ target, @@ -435,10 +435,7 @@ describe('services/building:configuration', () => { entry: { [target.name]: [path.join(target.paths.source, target.entry[buildType])], }, - definitions: { - 'process.env.NODE_ENV': `'${buildType}'`, - [versionVariable]: `"${version}"`, - }, + definitions: expect.any(Function), output: target.output[buildType], targetRules, copy: filesToCopy, @@ -520,6 +517,8 @@ describe('services/building:configuration', () => { const webpackPluginInfo = 'webpackPluginInfo'; let sut = null; let result = null; + let definitionsGenerator = null; + let generatedDefinitions = null; // When sut = new WebpackConfiguration( buildVersion, @@ -531,8 +530,15 @@ describe('services/building:configuration', () => { webpackPluginInfo ); result = sut.getConfig(target, buildType); + [[{ definitions: definitionsGenerator }]] = targetConfig.getConfig.mock.calls; + generatedDefinitions = definitionsGenerator(); // Then expect(result).toEqual(config); + expect(generatedDefinitions).toEqual({ + 'process.env.NODE_ENV': `'${buildType}'`, + [versionVariable]: `"${version}"`, + [target.configuration.defineOn]: JSON.stringify(targetBrowserConfig), + }); expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(1); expect(buildVersion.getVersion).toHaveBeenCalledTimes(1); expect(targetConfiguration).toHaveBeenCalledTimes(['global', 'byBuildType'].length); @@ -556,11 +562,7 @@ describe('services/building:configuration', () => { output: Object.assign({}, target.output[buildType], { jsChunks: target.output[buildType].js.replace(/\.js$/, '.[name].js'), }), - definitions: { - 'process.env.NODE_ENV': `'${buildType}'`, - [versionVariable]: `"${version}"`, - [target.configuration.defineOn]: JSON.stringify(targetBrowserConfig), - }, + definitions: expect.any(Function), targetRules, copy: filesToCopy, additionalWatch: targetBrowserConfigFiles, @@ -569,7 +571,8 @@ describe('services/building:configuration', () => { expect(pathUtils.join).toHaveBeenCalledWith(config.output.path); expect(targets.getFilesToCopy).toHaveBeenCalledTimes(1); expect(targets.getFilesToCopy).toHaveBeenCalledWith(target, buildType); - expect(targets.getBrowserTargetConfiguration).toHaveBeenCalledTimes(1); + expect(targets.getBrowserTargetConfiguration).toHaveBeenCalledTimes(2); + expect(targets.getBrowserTargetConfiguration).toHaveBeenCalledWith(target); expect(targets.getBrowserTargetConfiguration).toHaveBeenCalledWith(target); }); @@ -651,8 +654,8 @@ describe('services/building:configuration', () => { result = sut.getConfig(target, buildType); // Then expect(result).toEqual(config); - expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(1); - expect(buildVersion.getVersion).toHaveBeenCalledTimes(1); + expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(0); + expect(buildVersion.getVersion).toHaveBeenCalledTimes(0); expect(targetConfiguration).toHaveBeenCalledTimes(['global', 'byBuildType'].length); expect(targetConfiguration).toHaveBeenCalledWith( `webpack/${target.name}.config.js`, @@ -662,8 +665,7 @@ describe('services/building:configuration', () => { `webpack/${target.name}.${buildType}.config.js`, targetConfig ); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(1); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledWith(target, buildType); + expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(0); expect(targetConfig.getConfig).toHaveBeenCalledTimes(1); expect(targetConfig.getConfig).toHaveBeenCalledWith({ target, @@ -674,10 +676,7 @@ describe('services/building:configuration', () => { path.join(target.paths.source, target.entry[buildType]), ], }, - definitions: { - 'process.env.NODE_ENV': `'${buildType}'`, - [versionVariable]: `"${version}"`, - }, + definitions: expect.any(Function), output: Object.assign({}, target.output[buildType], { jsChunks: target.output[buildType].js.replace(/\.js$/, '.[name].js'), }), @@ -769,8 +768,8 @@ describe('services/building:configuration', () => { result = sut.getConfig(target, buildType); // Then expect(result).toEqual(expectedConfig); - expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(1); - expect(buildVersion.getVersion).toHaveBeenCalledTimes(1); + expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(0); + expect(buildVersion.getVersion).toHaveBeenCalledTimes(0); expect(targetConfiguration).toHaveBeenCalledTimes(['global', 'byBuildType'].length); expect(targetConfiguration).toHaveBeenCalledWith( `webpack/${target.name}.config.js`, @@ -780,8 +779,7 @@ describe('services/building:configuration', () => { `webpack/${target.name}.${buildType}.config.js`, targetConfig ); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(1); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledWith(target, buildType); + expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(0); expect(targetConfig.getConfig).toHaveBeenCalledTimes(1); expect(targetConfig.getConfig).toHaveBeenCalledWith({ target, @@ -789,10 +787,7 @@ describe('services/building:configuration', () => { entry: { [target.name]: [path.join(target.paths.source, target.entry[buildType])], }, - definitions: { - 'process.env.NODE_ENV': `'${buildType}'`, - [versionVariable]: `"${version}"`, - }, + definitions: expect.any(Function), output: Object.assign({}, target.output[buildType], { jsChunks: target.output[buildType].js.replace(/\.js$/, '.[name].js'), }), @@ -886,8 +881,8 @@ describe('services/building:configuration', () => { result = sut.getConfig(target, buildType); // Then expect(result).toEqual(expectedConfig); - expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(1); - expect(buildVersion.getVersion).toHaveBeenCalledTimes(1); + expect(buildVersion.getDefinitionVariable).toHaveBeenCalledTimes(0); + expect(buildVersion.getVersion).toHaveBeenCalledTimes(0); expect(targetConfiguration).toHaveBeenCalledTimes(['global', 'byBuildType'].length); expect(targetConfiguration).toHaveBeenCalledWith( `webpack/${target.name}.config.js`, @@ -897,8 +892,7 @@ describe('services/building:configuration', () => { `webpack/${target.name}.${buildType}.config.js`, targetConfig ); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(1); - expect(targets.loadTargetDotEnvFile).toHaveBeenCalledWith(target, buildType); + expect(targets.loadTargetDotEnvFile).toHaveBeenCalledTimes(0); expect(targetConfig.getConfig).toHaveBeenCalledTimes(1); expect(targetConfig.getConfig).toHaveBeenCalledWith({ target, @@ -906,10 +900,7 @@ describe('services/building:configuration', () => { entry: { [target.name]: [path.join(target.paths.source, target.entry[buildType])], }, - definitions: { - 'process.env.NODE_ENV': `'${buildType}'`, - [versionVariable]: `"${version}"`, - }, + definitions: expect.any(Function), output: Object.assign({}, target.output[buildType], { jsChunks: target.output[buildType].js.replace(/\.js$/, '.[name].js'), }), diff --git a/tests/services/configurations/browserDevelopmentConfiguration.test.js b/tests/services/configurations/browserDevelopmentConfiguration.test.js index 71aac5c..72461bc 100644 --- a/tests/services/configurations/browserDevelopmentConfiguration.test.js +++ b/tests/services/configurations/browserDevelopmentConfiguration.test.js @@ -22,7 +22,10 @@ const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); -const { ProjextWebpackOpenDevServer } = require('/src/plugins'); +const { + ProjextWebpackOpenDevServer, + ProjextWebpackRuntimeDefinitions, +} = require('/src/plugins'); const { WebpackBrowserDevelopmentConfiguration, @@ -40,6 +43,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { CopyWebpackPlugin.mockReset(); ExtraWatchWebpackPlugin.mockReset(); ProjextWebpackOpenDevServer.mockReset(); + ProjextWebpackRuntimeDefinitions.mockReset(); }); it('should be instantiated with all its dependencies', () => { @@ -108,8 +112,9 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -170,8 +175,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(0); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(0); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -224,8 +232,9 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -283,8 +292,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(0); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(0); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -335,8 +347,9 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -403,8 +416,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -454,8 +470,9 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -516,8 +533,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { defaultAttribute: 'async', }); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -578,7 +598,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }; const definitions = 'definitions'; const babelPolyfillEntry = `${webpackPluginInfo.name}/${webpackPluginInfo.babelPolyfill}`; - const targetEntry = 'index.js'; + const targetEntry = '/index.js'; const entry = { [target.name]: [ babelPolyfillEntry, @@ -659,8 +679,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [targetEntry], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -727,7 +750,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }; const definitions = 'definitions'; const babelPolyfillEntry = `${webpackPluginInfo.name}/${webpackPluginInfo.babelPolyfill}`; - const targetEntry = 'index.js'; + const targetEntry = '/index.js'; const entry = { [target.name]: [ babelPolyfillEntry, @@ -809,8 +832,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [targetEntry], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -880,7 +906,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }; const definitions = 'definitions'; const babelPolyfillEntry = `${webpackPluginInfo.name}/${webpackPluginInfo.babelPolyfill}`; - const targetEntry = 'index.js'; + const targetEntry = '/index.js'; const entry = { [target.name]: [ babelPolyfillEntry, @@ -956,8 +982,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { defaultAttribute: 'async', }); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [targetEntry], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -1030,7 +1059,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }; const definitions = 'definitions'; const babelPolyfillEntry = `${webpackPluginInfo.name}/${webpackPluginInfo.babelPolyfill}`; - const targetEntry = 'index.js'; + const targetEntry = '/index.js'; const entry = { [target.name]: [ babelPolyfillEntry, @@ -1113,8 +1142,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [targetEntry], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -1188,7 +1220,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }; const definitions = 'definitions'; const babelPolyfillEntry = `${webpackPluginInfo.name}/${webpackPluginInfo.babelPolyfill}`; - const targetEntry = 'index.js'; + const targetEntry = '/index.js'; const entry = { [target.name]: [ babelPolyfillEntry, @@ -1270,8 +1302,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [targetEntry], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -1343,7 +1378,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }; const definitions = 'definitions'; const babelPolyfillEntry = `${webpackPluginInfo.name}/${webpackPluginInfo.babelPolyfill}`; - const targetEntry = 'index.js'; + const targetEntry = '/index.js'; const entry = { [target.name]: [ babelPolyfillEntry, @@ -1426,8 +1461,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [targetEntry], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); @@ -1499,7 +1537,7 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { }; const definitions = 'definitions'; const babelPolyfillEntry = `${webpackPluginInfo.name}/${webpackPluginInfo.babelPolyfill}`; - const targetEntry = 'index.js'; + const targetEntry = '/index.js'; const entry = { [target.name]: [ babelPolyfillEntry, @@ -1582,8 +1620,11 @@ describe('services/configurations:browserDevelopmentConfiguration', () => { expect(webpackMock.HotModuleReplacementPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NamedModulesPluginMock).toHaveBeenCalledTimes(1); expect(webpackMock.NoEmitOnErrorsPluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [targetEntry], + definitions + ); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledWith(copy); diff --git a/tests/services/configurations/browserProductionConfiguration.test.js b/tests/services/configurations/browserProductionConfiguration.test.js index ce91724..412dfb6 100644 --- a/tests/services/configurations/browserProductionConfiguration.test.js +++ b/tests/services/configurations/browserProductionConfiguration.test.js @@ -25,6 +25,7 @@ const TerserPlugin = require('terser-webpack-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); +const { ProjextWebpackRuntimeDefinitions } = require('/src/plugins'); const { WebpackBrowserProductionConfiguration, @@ -43,6 +44,7 @@ describe('services/configurations:browserProductionConfiguration', () => { CompressionPlugin.mockReset(); CopyWebpackPlugin.mockReset(); ExtraWatchWebpackPlugin.mockReset(); + ProjextWebpackRuntimeDefinitions.mockReset(); }); it('should be instantiated with all its dependencies', () => { @@ -104,8 +106,9 @@ describe('services/configurations:browserProductionConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -164,8 +167,11 @@ describe('services/configurations:browserProductionConfiguration', () => { expect(ScriptExtHtmlWebpackPlugin).toHaveBeenCalledWith({ defaultAttribute: 'async', }); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(TerserPlugin).toHaveBeenCalledTimes(1); expect(TerserPlugin).toHaveBeenCalledWith({ sourceMap: false, @@ -220,8 +226,9 @@ describe('services/configurations:browserProductionConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -280,8 +287,11 @@ describe('services/configurations:browserProductionConfiguration', () => { expect(ScriptExtHtmlWebpackPlugin).toHaveBeenCalledWith({ defaultAttribute: 'async', }); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(TerserPlugin).toHaveBeenCalledTimes(0); expect(OptimizeCssAssetsPlugin).toHaveBeenCalledTimes(1); expect(CopyWebpackPlugin).toHaveBeenCalledTimes(1); @@ -330,8 +340,9 @@ describe('services/configurations:browserProductionConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -391,8 +402,11 @@ describe('services/configurations:browserProductionConfiguration', () => { expect(ScriptExtHtmlWebpackPlugin).toHaveBeenCalledWith({ defaultAttribute: 'async', }); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(TerserPlugin).toHaveBeenCalledTimes(1); expect(TerserPlugin).toHaveBeenCalledWith({ sourceMap: false, @@ -446,8 +460,9 @@ describe('services/configurations:browserProductionConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -503,8 +518,11 @@ describe('services/configurations:browserProductionConfiguration', () => { expect(ScriptExtHtmlWebpackPlugin).toHaveBeenCalledWith({ defaultAttribute: 'async', }); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(TerserPlugin).toHaveBeenCalledTimes(1); expect(TerserPlugin).toHaveBeenCalledWith({ sourceMap: false, @@ -558,8 +576,9 @@ describe('services/configurations:browserProductionConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -619,8 +638,11 @@ describe('services/configurations:browserProductionConfiguration', () => { expect(ScriptExtHtmlWebpackPlugin).toHaveBeenCalledWith({ defaultAttribute: 'async', }); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(TerserPlugin).toHaveBeenCalledTimes(1); expect(TerserPlugin).toHaveBeenCalledWith({ sourceMap: true, @@ -672,8 +694,9 @@ describe('services/configurations:browserProductionConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -722,8 +745,11 @@ describe('services/configurations:browserProductionConfiguration', () => { }); expect(HtmlWebpackPlugin).toHaveBeenCalledTimes(0); expect(ScriptExtHtmlWebpackPlugin).toHaveBeenCalledTimes(0); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(TerserPlugin).toHaveBeenCalledTimes(1); expect(TerserPlugin).toHaveBeenCalledWith({ sourceMap: false, @@ -775,8 +801,9 @@ describe('services/configurations:browserProductionConfiguration', () => { }, }; const definitions = 'definitions'; + const entryFile = '/index.js'; const entry = { - [target.name]: ['index.js'], + [target.name]: [entryFile], }; const output = { js: 'statics/js/build.js', @@ -825,8 +852,11 @@ describe('services/configurations:browserProductionConfiguration', () => { }); expect(HtmlWebpackPlugin).toHaveBeenCalledTimes(0); expect(ScriptExtHtmlWebpackPlugin).toHaveBeenCalledTimes(0); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledTimes(1); - expect(webpackMock.DefinePluginMock).toHaveBeenCalledWith(definitions); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledTimes(1); + expect(ProjextWebpackRuntimeDefinitions).toHaveBeenCalledWith( + [entryFile], + definitions + ); expect(TerserPlugin).toHaveBeenCalledTimes(1); expect(TerserPlugin).toHaveBeenCalledWith({ sourceMap: false,