From 0ad6ad40d07a32aa0698a724b45a948ce211f909 Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 7 Jan 2023 22:38:05 -1000 Subject: [PATCH 01/13] wip --- lib/install/config/shakapacker.yml | 9 +++++++++ package/environments/base.js | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/install/config/shakapacker.yml b/lib/install/config/shakapacker.yml index df5184bf0..738766bd1 100644 --- a/lib/install/config/shakapacker.yml +++ b/lib/install/config/shakapacker.yml @@ -1,4 +1,5 @@ # Note: You must restart bin/shakapacker-dev-server for changes to take effect +# This file contains the defaults used by shakapacker. default: &default source_path: app/javascript @@ -44,6 +45,11 @@ default: &default # Select whether the compiler will use SHA digest ('digest' option) or most most recent modified timestamp ('mtime') to determine freshness compiler_strategy: digest + # Select whether the compiler will always use a content hash and not just in production + # Don't use contentHash except for production for performance + # https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling + useContentHash: false + development: <<: *default compile: true @@ -105,5 +111,8 @@ production: # Production depends on precompilation of packs prior to booting for performance. compile: false + # Use content hash for naming assets. Cannot be overridden by for production. + useContentHash: true + # Cache manifest.json for performance cache_manifest: true diff --git a/package/environments/base.js b/package/environments/base.js index 6b11ef821..4e90e727f 100644 --- a/package/environments/base.js +++ b/package/environments/base.js @@ -55,6 +55,10 @@ const getModulePaths = () => { return result } +console.log("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); +console.log("config.useContentHash: " + config.useContentHash); +console.log("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); + const getPlugins = () => { const plugins = [ new webpack.EnvironmentPlugin(process.env), @@ -68,7 +72,7 @@ const getPlugins = () => { ] if (moduleExists('css-loader') && moduleExists('mini-css-extract-plugin')) { - const hash = isProduction ? '-[contenthash:8]' : '' + const hash = config.useContentHash ? '-[contenthash:8]' : '' const MiniCssExtractPlugin = require('mini-css-extract-plugin') plugins.push( new MiniCssExtractPlugin({ @@ -87,7 +91,7 @@ const getPlugins = () => { // Don't use contentHash except for production for performance // https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling -const hash = isProduction ? '-[contenthash]' : '' +const hash = config.useContentHash ? '-[contenthash]' : '' module.exports = { mode: 'production', output: { From c9653465bec8f11539ba0dc9a726269c90af3830 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Wed, 14 Jun 2023 16:46:16 +0330 Subject: [PATCH 02/13] Fix eslint issues --- package/environments/base.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/package/environments/base.js b/package/environments/base.js index 4e90e727f..d49b863a6 100644 --- a/package/environments/base.js +++ b/package/environments/base.js @@ -7,7 +7,6 @@ const { sync: globSync } = require('glob') const WebpackAssetsManifest = require('webpack-assets-manifest') const webpack = require('webpack') const rules = require('../rules') -const { isProduction } = require('../env') const config = require('../config') const { moduleExists } = require('../utils/helpers') @@ -55,10 +54,6 @@ const getModulePaths = () => { return result } -console.log("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); -console.log("config.useContentHash: " + config.useContentHash); -console.log("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); - const getPlugins = () => { const plugins = [ new webpack.EnvironmentPlugin(process.env), From fad12e8a878c645873cc15f468c9ebb2dd907fd4 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Wed, 14 Jun 2023 17:27:12 +0330 Subject: [PATCH 03/13] Update tests --- package/environments/__tests__/base-bc.js | 4 ++-- package/environments/__tests__/base.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package/environments/__tests__/base-bc.js b/package/environments/__tests__/base-bc.js index 22a1eaeab..bfb53f597 100644 --- a/package/environments/__tests__/base-bc.js +++ b/package/environments/__tests__/base-bc.js @@ -65,9 +65,9 @@ describe('Base config', () => { }) test('should return output', () => { - expect(baseConfig.output.filename).toEqual('js/[name].js') + expect(baseConfig.output.filename).toEqual('js/[name]-[contenthash].js') expect(baseConfig.output.chunkFilename).toEqual( - 'js/[name].chunk.js' + 'js/[name]-[contenthash].chunk.js' ) }) diff --git a/package/environments/__tests__/base.js b/package/environments/__tests__/base.js index d30127738..4bd6121e4 100644 --- a/package/environments/__tests__/base.js +++ b/package/environments/__tests__/base.js @@ -65,9 +65,9 @@ describe('Base config', () => { }) test('should return output', () => { - expect(baseConfig.output.filename).toEqual('js/[name].js') + expect(baseConfig.output.filename).toEqual('js/[name]-[contenthash].js') expect(baseConfig.output.chunkFilename).toEqual( - 'js/[name].chunk.js' + 'js/[name]-[contenthash].chunk.js' ) }) From 3092956f974a7e47b3b71723346ee222341dfef0 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Fri, 16 Jun 2023 19:59:47 +0330 Subject: [PATCH 04/13] Add test for useContentHash --- package/environments/__tests__/development.js | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 package/environments/__tests__/development.js diff --git a/package/environments/__tests__/development.js b/package/environments/__tests__/development.js new file mode 100644 index 000000000..2e462f9ce --- /dev/null +++ b/package/environments/__tests__/development.js @@ -0,0 +1,51 @@ +/* global test expect, describe, afterAll, beforeEach */ + +process.env['RAILS_ENV'] = 'development' + +const { chdirTestApp, resetEnv } = require('../../utils/helpers') +const rootPath = process.cwd() +chdirTestApp() + +describe('Development specific config', () => { + beforeEach(() => jest.resetModules() && resetEnv()) + afterAll(() => process.chdir(rootPath)) + + describe('with config.useContentHash = true', () => { + test('should return output with contentHash', () => { + const config = require("../../config"); + config.useContentHash = true + const environmnetConfig = require('../development') + + expect(environmnetConfig.output.filename).toEqual('js/[name]-[contenthash].js') + expect(environmnetConfig.output.chunkFilename).toEqual( + 'js/[name]-[contenthash].chunk.js' + ) + }) + }) + + describe('with config.useContentHash = false', () => { + test('should return output with contentHash', () => { + const config = require("../../config"); + config.useContentHash = false + const environmnetConfig = require('../development') + + expect(environmnetConfig.output.filename).toEqual('js/[name].js') + expect(environmnetConfig.output.chunkFilename).toEqual( + 'js/[name].chunk.js' + ) + }) + }) + + describe('with unset config.useContentHash', () => { + test('should return output with contentHash', () => { + const config = require("../../config"); + delete config.useContentHash + const environmnetConfig = require('../development') + + expect(environmnetConfig.output.filename).toEqual('js/[name].js') + expect(environmnetConfig.output.chunkFilename).toEqual( + 'js/[name].chunk.js' + ) + }) + }) +}) From 7bd1c7149412beb7075b4f6f0b4f2d7c8539651e Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Fri, 16 Jun 2023 20:07:16 +0330 Subject: [PATCH 05/13] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3647cf614..483253b13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ _Please add entries here for your pull requests that are not yet released._ - Set CSS modules mode depending on file type. [PR 261](https://github.com/shakacode/shakapacker/pull/261) by [talyuk](https://github.com/talyuk). - All standard webpack entries with the camelCase format are now supported in `shakapacker.yml` in snake_case format. [PR276](https://github.com/shakacode/shakapacker/pull/276) by [ahangarha](https://github.com/ahangarha). - The `shakapacker:install` rake task now has an option to force overriding files using `FORCE=true` environment variable [PR311](https://github.com/shakacode/shakapacker/pull/311) by [ahangarha](https://github.com/ahangarha). +- Allow configuration of use of contentHash for specific environment [PR 234](https://github.com/shakacode/shakapacker/pull/234) by [justin808](https://github/justin808). ### Changed - Rename Webpacker to Shakapacker in the entire project including config files, binstubs, environment variables, etc. with a high degree of backward compatibility. From 5c22934d16af5da1fed97a797f7a68f41f81cb6b Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Fri, 16 Jun 2023 20:19:00 +0330 Subject: [PATCH 06/13] Update docs --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2dd5694b1..6de873a67 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,8 @@ Webpack intelligently includes only necessary files. In this example, the file ` `nested_entries` allows you to have webpack entry points nested in subdirectories. This defaults to false so you don't accidentally create entry points for an entire tree of files. In other words, with `nested_entries: false`, you can have your entire `source_path` used for your source (using the `source_entry_path: /`) and you place files at the top level that you want as entry points. `nested_entries: true` allows you to have entries that are in subdirectories. This is useful if you have entries that are generated, so you can have a `generated` subdirectory and easily separate generated files from the rest of your codebase. +To enable/disable the usage of contentHash in any specific environment, add/modify `useContentHash` with a boolean value in `config/shakapacker.yml`. This feature is disabled for all environments except production by default. Notice that despite the possibility of enabling this option for the development environment, [it is not recommended](https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling). + #### Setting custom config path You can use the environment variable `SHAKAPACKER_CONFIG` to enforce a particular path to the config file rather than the default `config/shakapacker.yml`. From a7cc75b90d87fcf633bca9a43bd5edce620f1589 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Wed, 21 Jun 2023 20:18:47 +0330 Subject: [PATCH 07/13] Improve test env and titles --- package/environments/__tests__/development.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/package/environments/__tests__/development.js b/package/environments/__tests__/development.js index 2e462f9ce..8684ee952 100644 --- a/package/environments/__tests__/development.js +++ b/package/environments/__tests__/development.js @@ -1,17 +1,19 @@ /* global test expect, describe, afterAll, beforeEach */ -process.env['RAILS_ENV'] = 'development' - const { chdirTestApp, resetEnv } = require('../../utils/helpers') const rootPath = process.cwd() chdirTestApp() describe('Development specific config', () => { - beforeEach(() => jest.resetModules() && resetEnv()) + beforeEach(() => { + jest.resetModules() + resetEnv() + process.env['NODE_ENV'] = 'development' + }) afterAll(() => process.chdir(rootPath)) describe('with config.useContentHash = true', () => { - test('should return output with contentHash', () => { + test('sets filename to use contentHash', () => { const config = require("../../config"); config.useContentHash = true const environmnetConfig = require('../development') @@ -24,7 +26,7 @@ describe('Development specific config', () => { }) describe('with config.useContentHash = false', () => { - test('should return output with contentHash', () => { + test('sets filename without using contentHash', () => { const config = require("../../config"); config.useContentHash = false const environmnetConfig = require('../development') @@ -37,7 +39,7 @@ describe('Development specific config', () => { }) describe('with unset config.useContentHash', () => { - test('should return output with contentHash', () => { + test('sets filename without using contentHash', () => { const config = require("../../config"); delete config.useContentHash const environmnetConfig = require('../development') From 04a602dbe2ad9e82a7a4c2e2f5458d21e0ff2341 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Wed, 21 Jun 2023 20:33:03 +0330 Subject: [PATCH 08/13] Force using contentHash in production --- package/environments/__tests__/production.js | 53 ++++++++++++++++++++ package/environments/base.js | 6 ++- package/environments/production.js | 9 ++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 package/environments/__tests__/production.js diff --git a/package/environments/__tests__/production.js b/package/environments/__tests__/production.js new file mode 100644 index 000000000..2ba55ca7a --- /dev/null +++ b/package/environments/__tests__/production.js @@ -0,0 +1,53 @@ +/* global test expect, describe, afterAll, beforeEach */ + +const { chdirTestApp, resetEnv } = require('../../utils/helpers') +const rootPath = process.cwd() +chdirTestApp() + +describe('Production specific config', () => { + beforeEach(() => { + jest.resetModules() + resetEnv() + process.env['NODE_ENV'] = 'production' + }) + afterAll(() => process.chdir(rootPath)) + + describe('with config.useContentHash = true', () => { + test('sets filename to use contentHash', () => { + const config = require("../../config"); + config.useContentHash = true + const environmnetConfig = require('../production') + + expect(environmnetConfig.output.filename).toEqual('js/[name]-[contenthash].js') + expect(environmnetConfig.output.chunkFilename).toEqual( + 'js/[name]-[contenthash].chunk.js' + ) + }) + }) + + describe('with config.useContentHash = false', () => { + test('sets filename to use contentHash', () => { + const config = require("../../config"); + config.useContentHash = false + const environmnetConfig = require('../production') + + expect(environmnetConfig.output.filename).toEqual('js/[name]-[contenthash].js') + expect(environmnetConfig.output.chunkFilename).toEqual( + 'js/[name]-[contenthash].chunk.js' + ) + }) + }) + + describe('with unset config.useContentHash', () => { + test('sets filename to use contentHash', () => { + const config = require("../../config"); + delete config.useContentHash + const environmnetConfig = require('../production') + + expect(environmnetConfig.output.filename).toEqual('js/[name]-[contenthash].js') + expect(environmnetConfig.output.chunkFilename).toEqual( + 'js/[name]-[contenthash].chunk.js' + ) + }) + }) +}) diff --git a/package/environments/base.js b/package/environments/base.js index d49b863a6..e047f4e19 100644 --- a/package/environments/base.js +++ b/package/environments/base.js @@ -8,6 +8,7 @@ const WebpackAssetsManifest = require('webpack-assets-manifest') const webpack = require('webpack') const rules = require('../rules') const config = require('../config') +const { isProduction } = require('../env') const { moduleExists } = require('../utils/helpers') const getEntryObject = () => { @@ -67,7 +68,7 @@ const getPlugins = () => { ] if (moduleExists('css-loader') && moduleExists('mini-css-extract-plugin')) { - const hash = config.useContentHash ? '-[contenthash:8]' : '' + const hash = isProduction || config.useContentHash ? '-[contenthash:8]' : '' const MiniCssExtractPlugin = require('mini-css-extract-plugin') plugins.push( new MiniCssExtractPlugin({ @@ -86,7 +87,8 @@ const getPlugins = () => { // Don't use contentHash except for production for performance // https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling -const hash = config.useContentHash ? '-[contenthash]' : '' +const hash = isProduction || config.useContentHash ? '-[contenthash]' : '' + module.exports = { mode: 'production', output: { diff --git a/package/environments/production.js b/package/environments/production.js index 3eff2d76d..e874a2b6d 100644 --- a/package/environments/production.js +++ b/package/environments/production.js @@ -6,6 +6,7 @@ const CompressionPlugin = require('compression-webpack-plugin') const TerserPlugin = require('terser-webpack-plugin') const baseConfig = require('./base') const { moduleExists } = require('../utils/helpers') +const config = require('../config') const getPlugins = () => { const plugins = [] @@ -76,4 +77,12 @@ const productionConfig = { } } +if (config.useContentHash === true) { + // eslint-disable-next-line no-console + console.warn(`⚠️ WARNING +Setting 'useContentHash' to 'false' in production environment is not allowed! +It is considered true regardless of the value set in the config file. +`) +} + module.exports = merge(baseConfig, productionConfig) From 7c811ec7fa67cab84c42384778213ea883bf5bfe Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Thu, 22 Jun 2023 09:33:40 +0330 Subject: [PATCH 09/13] Improve documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6de873a67..ebc415874 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,7 @@ Webpack intelligently includes only necessary files. In this example, the file ` `nested_entries` allows you to have webpack entry points nested in subdirectories. This defaults to false so you don't accidentally create entry points for an entire tree of files. In other words, with `nested_entries: false`, you can have your entire `source_path` used for your source (using the `source_entry_path: /`) and you place files at the top level that you want as entry points. `nested_entries: true` allows you to have entries that are in subdirectories. This is useful if you have entries that are generated, so you can have a `generated` subdirectory and easily separate generated files from the rest of your codebase. -To enable/disable the usage of contentHash in any specific environment, add/modify `useContentHash` with a boolean value in `config/shakapacker.yml`. This feature is disabled for all environments except production by default. Notice that despite the possibility of enabling this option for the development environment, [it is not recommended](https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling). +To enable/disable the usage of contentHash in any node environment (specified using the `NODE_ENV` environment variable), add/modify `useContentHash` with a boolean value in `config/shakapacker.yml`. This feature is disabled for all environments except production by default. Notice that despite the possibility of enabling this option for the development environment, [it is not recommended](https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling). Also, notice that content hash gets added to the file names in the production environment regardless of the value set for useContentHash in the config file. #### Setting custom config path From c64a51491fa1bf5493f0005a495680ee370e7761 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Thu, 22 Jun 2023 09:38:00 +0330 Subject: [PATCH 10/13] Improve warning message for node env --- package/environments/production.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/environments/production.js b/package/environments/production.js index e874a2b6d..5b963c494 100644 --- a/package/environments/production.js +++ b/package/environments/production.js @@ -80,7 +80,7 @@ const productionConfig = { if (config.useContentHash === true) { // eslint-disable-next-line no-console console.warn(`⚠️ WARNING -Setting 'useContentHash' to 'false' in production environment is not allowed! +Setting 'useContentHash' to 'false' in production node environment is not allowed! It is considered true regardless of the value set in the config file. `) } From 98f7b8bb85f7ef3122044531f1445e77483a58b8 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Thu, 22 Jun 2023 09:47:34 +0330 Subject: [PATCH 11/13] Specify NODE_ENV in the warning message --- package/environments/production.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/environments/production.js b/package/environments/production.js index 5b963c494..966a90d05 100644 --- a/package/environments/production.js +++ b/package/environments/production.js @@ -80,8 +80,8 @@ const productionConfig = { if (config.useContentHash === true) { // eslint-disable-next-line no-console console.warn(`⚠️ WARNING -Setting 'useContentHash' to 'false' in production node environment is not allowed! -It is considered true regardless of the value set in the config file. +Setting 'useContentHash' to 'false' in the production environment (specified by NODE_ENV environment variable) is not allowed! +ContentHash gets added to the filenames regardless of the setting useContentHash to false. `) } From daf053200be3b76d46e9bdcd7ceb467c0aa7b803 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Thu, 22 Jun 2023 09:51:00 +0330 Subject: [PATCH 12/13] Improve documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebc415874..0abbd2f31 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,7 @@ Webpack intelligently includes only necessary files. In this example, the file ` `nested_entries` allows you to have webpack entry points nested in subdirectories. This defaults to false so you don't accidentally create entry points for an entire tree of files. In other words, with `nested_entries: false`, you can have your entire `source_path` used for your source (using the `source_entry_path: /`) and you place files at the top level that you want as entry points. `nested_entries: true` allows you to have entries that are in subdirectories. This is useful if you have entries that are generated, so you can have a `generated` subdirectory and easily separate generated files from the rest of your codebase. -To enable/disable the usage of contentHash in any node environment (specified using the `NODE_ENV` environment variable), add/modify `useContentHash` with a boolean value in `config/shakapacker.yml`. This feature is disabled for all environments except production by default. Notice that despite the possibility of enabling this option for the development environment, [it is not recommended](https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling). Also, notice that content hash gets added to the file names in the production environment regardless of the value set for useContentHash in the config file. +To enable/disable the usage of contentHash in any node environment (specified using the `NODE_ENV` environment variable), add/modify `useContentHash` with a boolean value in `config/shakapacker.yml`. This feature is disabled for all environments except production by default. You may not disable the content hash for a `NODE_ENV` of production as that would break the browser caching of assets. Notice that despite the possibility of enabling this option for the development environment, [it is not recommended](https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling). #### Setting custom config path From 15ed9727abe698a0f02c825005bd21fdfd17074c Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Thu, 22 Jun 2023 11:40:42 +0500 Subject: [PATCH 13/13] Update production.js --- package/environments/production.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/environments/production.js b/package/environments/production.js index 966a90d05..955b9c184 100644 --- a/package/environments/production.js +++ b/package/environments/production.js @@ -81,7 +81,7 @@ if (config.useContentHash === true) { // eslint-disable-next-line no-console console.warn(`⚠️ WARNING Setting 'useContentHash' to 'false' in the production environment (specified by NODE_ENV environment variable) is not allowed! -ContentHash gets added to the filenames regardless of the setting useContentHash to false. +Content hashes get added to the filenames regardless of setting useContentHash in 'shakapacker.yml' to false. `) }