shakapacker 6.0.0.rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +4 -0
  3. data/.eslintrc.js +14 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
  5. data/.github/ISSUE_TEMPLATE/feature-request.md +18 -0
  6. data/.github/workflows/jest.yml +30 -0
  7. data/.github/workflows/js-lint.yml +31 -0
  8. data/.github/workflows/rubocop.yml +39 -0
  9. data/.github/workflows/ruby.yml +48 -0
  10. data/.gitignore +13 -0
  11. data/.node-version +1 -0
  12. data/.rubocop.yml +229 -0
  13. data/CHANGELOG.md +32 -0
  14. data/CONTRIBUTING.md +62 -0
  15. data/Gemfile +13 -0
  16. data/Gemfile.lock +183 -0
  17. data/MIT-LICENSE +20 -0
  18. data/README.md +666 -0
  19. data/Rakefile +11 -0
  20. data/config/README.md +3 -0
  21. data/config/webpacker.yml +1 -0
  22. data/docs/customizing_babel_config.md +59 -0
  23. data/docs/deployment.md +116 -0
  24. data/docs/developing_webpacker.md +29 -0
  25. data/docs/troubleshooting.md +212 -0
  26. data/docs/v6_upgrade.md +158 -0
  27. data/gemfiles/Gemfile-rails-edge +12 -0
  28. data/gemfiles/Gemfile-rails.5.2.x +9 -0
  29. data/gemfiles/Gemfile-rails.6.0.x +9 -0
  30. data/gemfiles/Gemfile-rails.6.1.x +12 -0
  31. data/lib/install/application.js +15 -0
  32. data/lib/install/bin/webpacker +15 -0
  33. data/lib/install/bin/webpacker-dev-server +18 -0
  34. data/lib/install/bin/yarn +18 -0
  35. data/lib/install/binstubs.rb +4 -0
  36. data/lib/install/config/webpack/webpack.config.js +5 -0
  37. data/lib/install/config/webpacker.yml +64 -0
  38. data/lib/install/package.json +15 -0
  39. data/lib/install/template.rb +100 -0
  40. data/lib/shakapacker/utils/git_utils.rb +23 -0
  41. data/lib/shakapacker/utils/version_syntax_converter.rb +24 -0
  42. data/lib/tasks/webpacker/binstubs.rake +15 -0
  43. data/lib/tasks/webpacker/check_binstubs.rake +12 -0
  44. data/lib/tasks/webpacker/check_node.rake +31 -0
  45. data/lib/tasks/webpacker/check_yarn.rake +33 -0
  46. data/lib/tasks/webpacker/clean.rake +25 -0
  47. data/lib/tasks/webpacker/clobber.rake +20 -0
  48. data/lib/tasks/webpacker/compile.rake +45 -0
  49. data/lib/tasks/webpacker/info.rake +21 -0
  50. data/lib/tasks/webpacker/install.rake +17 -0
  51. data/lib/tasks/webpacker/verify_config.rake +14 -0
  52. data/lib/tasks/webpacker/verify_install.rake +4 -0
  53. data/lib/tasks/webpacker/yarn_install.rake +18 -0
  54. data/lib/tasks/webpacker.rake +19 -0
  55. data/lib/tasks/yarn.rake +38 -0
  56. data/lib/webpacker/commands.rb +79 -0
  57. data/lib/webpacker/compiler.rb +130 -0
  58. data/lib/webpacker/configuration.rb +111 -0
  59. data/lib/webpacker/dev_server.rb +72 -0
  60. data/lib/webpacker/dev_server_proxy.rb +33 -0
  61. data/lib/webpacker/dev_server_runner.rb +96 -0
  62. data/lib/webpacker/env.rb +43 -0
  63. data/lib/webpacker/helper.rb +161 -0
  64. data/lib/webpacker/instance.rb +41 -0
  65. data/lib/webpacker/manifest.rb +120 -0
  66. data/lib/webpacker/railtie.rb +63 -0
  67. data/lib/webpacker/runner.rb +23 -0
  68. data/lib/webpacker/version.rb +4 -0
  69. data/lib/webpacker/webpack_runner.rb +58 -0
  70. data/lib/webpacker.rb +46 -0
  71. data/package/__tests__/config.js +34 -0
  72. data/package/__tests__/dev_server.js +45 -0
  73. data/package/__tests__/development.js +35 -0
  74. data/package/__tests__/env.js +58 -0
  75. data/package/__tests__/index.js +9 -0
  76. data/package/__tests__/production.js +29 -0
  77. data/package/__tests__/staging.js +30 -0
  78. data/package/__tests__/test.js +25 -0
  79. data/package/babel/preset.js +41 -0
  80. data/package/config.js +32 -0
  81. data/package/configPath.js +3 -0
  82. data/package/dev_server.js +20 -0
  83. data/package/env.js +27 -0
  84. data/package/environments/__tests__/base.js +69 -0
  85. data/package/environments/base.js +116 -0
  86. data/package/environments/development.js +55 -0
  87. data/package/environments/production.js +79 -0
  88. data/package/environments/test.js +3 -0
  89. data/package/index.js +33 -0
  90. data/package/inliningCss.js +7 -0
  91. data/package/rules/babel.js +30 -0
  92. data/package/rules/coffee.js +6 -0
  93. data/package/rules/css.js +3 -0
  94. data/package/rules/erb.js +15 -0
  95. data/package/rules/file.js +23 -0
  96. data/package/rules/index.js +18 -0
  97. data/package/rules/less.js +22 -0
  98. data/package/rules/raw.js +5 -0
  99. data/package/rules/sass.js +16 -0
  100. data/package/rules/stylus.js +26 -0
  101. data/package/utils/get_style_rule.js +37 -0
  102. data/package/utils/helpers.js +51 -0
  103. data/package.json +71 -0
  104. data/rakelib/release.rake +57 -0
  105. data/test/command_test.rb +109 -0
  106. data/test/compiler_test.rb +68 -0
  107. data/test/configuration_test.rb +78 -0
  108. data/test/dev_server_runner_test.rb +81 -0
  109. data/test/dev_server_test.rb +47 -0
  110. data/test/engine_rake_tasks_test.rb +39 -0
  111. data/test/env_test.rb +23 -0
  112. data/test/helper_test.rb +159 -0
  113. data/test/manifest_test.rb +89 -0
  114. data/test/mounted_app/Rakefile +4 -0
  115. data/test/mounted_app/test/dummy/Rakefile +3 -0
  116. data/test/mounted_app/test/dummy/bin/rails +3 -0
  117. data/test/mounted_app/test/dummy/bin/rake +3 -0
  118. data/test/mounted_app/test/dummy/config/application.rb +10 -0
  119. data/test/mounted_app/test/dummy/config/environment.rb +3 -0
  120. data/test/mounted_app/test/dummy/config/webpacker.yml +75 -0
  121. data/test/mounted_app/test/dummy/config.ru +5 -0
  122. data/test/mounted_app/test/dummy/package.json +7 -0
  123. data/test/rake_tasks_test.rb +71 -0
  124. data/test/test_app/Rakefile +3 -0
  125. data/test/test_app/app/packs/entrypoints/application.js +10 -0
  126. data/test/test_app/app/packs/entrypoints/multi_entry.css +4 -0
  127. data/test/test_app/app/packs/entrypoints/multi_entry.js +4 -0
  128. data/test/test_app/bin/webpacker +14 -0
  129. data/test/test_app/bin/webpacker-dev-server +14 -0
  130. data/test/test_app/config/application.rb +11 -0
  131. data/test/test_app/config/environment.rb +4 -0
  132. data/test/test_app/config/initializers/inspect_autoload_paths.rb +1 -0
  133. data/test/test_app/config/webpack/webpack.config.js +0 -0
  134. data/test/test_app/config/webpacker.yml +77 -0
  135. data/test/test_app/config/webpacker_other_location.yml +79 -0
  136. data/test/test_app/config/webpacker_public_root.yml +18 -0
  137. data/test/test_app/config.ru +5 -0
  138. data/test/test_app/package.json +13 -0
  139. data/test/test_app/public/packs/manifest.json +50 -0
  140. data/test/test_app/some.config.js +0 -0
  141. data/test/test_app/yarn.lock +11 -0
  142. data/test/test_helper.rb +33 -0
  143. data/test/webpack_runner_test.rb +57 -0
  144. data/test/webpacker_test.rb +34 -0
  145. data/webpacker.gemspec +31 -0
  146. data/yarn.lock +4029 -0
  147. metadata +331 -0
@@ -0,0 +1,6 @@
1
+ const { canProcess } = require('../utils/helpers')
2
+
3
+ module.exports = canProcess('coffee-loader', (resolvedPath) => ({
4
+ test: /\.coffee(\.erb)?$/,
5
+ use: [{ loader: resolvedPath }]
6
+ }))
@@ -0,0 +1,3 @@
1
+ const getStyleRule = require('../utils/get_style_rule')
2
+
3
+ module.exports = getStyleRule(/\.(css)$/i)
@@ -0,0 +1,15 @@
1
+ const { canProcess } = require('../utils/helpers')
2
+
3
+ const runner = /^win/.test(process.platform) ? 'ruby ' : ''
4
+
5
+ module.exports = canProcess('rails-erb-loader', (resolvedPath) => ({
6
+ test: /\.erb$/,
7
+ enforce: 'pre',
8
+ exclude: /node_modules/,
9
+ use: [
10
+ {
11
+ loader: resolvedPath,
12
+ options: { runner: `${runner}bin/rails runner` }
13
+ }
14
+ ]
15
+ }))
@@ -0,0 +1,23 @@
1
+ module.exports = {
2
+ test: [
3
+ /\.bmp$/,
4
+ /\.gif$/,
5
+ /\.jpe?g$/,
6
+ /\.png$/,
7
+ /\.tiff$/,
8
+ /\.ico$/,
9
+ /\.avif$/,
10
+ /\.webp$/,
11
+ /\.eot$/,
12
+ /\.otf$/,
13
+ /\.ttf$/,
14
+ /\.woff$/,
15
+ /\.woff2$/,
16
+ /\.svg$/
17
+ ],
18
+ exclude: [/\.(js|mjs|jsx|ts|tsx)$/],
19
+ type: 'asset/resource',
20
+ generator: {
21
+ filename: 'static/[name]-[hash][ext][query]'
22
+ }
23
+ }
@@ -0,0 +1,18 @@
1
+ /* eslint global-require: 0 */
2
+ /* eslint import/no-dynamic-require: 0 */
3
+
4
+ const rules = {
5
+ raw: require('./raw'),
6
+ file: require('./file'),
7
+ css: require('./css'),
8
+ sass: require('./sass'),
9
+ babel: require('./babel'),
10
+ erb: require('./erb'),
11
+ coffee: require('./coffee'),
12
+ less: require('./less'),
13
+ stylus: require('./stylus')
14
+ }
15
+
16
+ module.exports = Object.keys(rules)
17
+ .filter((key) => !!rules[key])
18
+ .map((key) => rules[key])
@@ -0,0 +1,22 @@
1
+ const path = require('path')
2
+ const { canProcess } = require('../utils/helpers')
3
+ const getStyleRule = require('../utils/get_style_rule')
4
+
5
+ const {
6
+ additional_paths: paths,
7
+ source_path: sourcePath
8
+ } = require('../config')
9
+
10
+ module.exports = canProcess('less-loader', (resolvedPath) =>
11
+ getStyleRule(/\.(less)(\.erb)?$/i, [
12
+ {
13
+ loader: resolvedPath,
14
+ options: {
15
+ lessOptions: {
16
+ paths: [path.resolve(__dirname, 'node_modules'), sourcePath, ...paths]
17
+ },
18
+ sourceMap: true
19
+ }
20
+ }
21
+ ])
22
+ )
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ test: [/\.html$/],
3
+ exclude: [/\.(js|mjs|jsx|ts|tsx)$/],
4
+ type: 'asset/source'
5
+ }
@@ -0,0 +1,16 @@
1
+ /* eslint global-require: 0 */
2
+
3
+ const getStyleRule = require('../utils/get_style_rule')
4
+ const { canProcess } = require('../utils/helpers')
5
+ const { additional_paths: includePaths } = require('../config')
6
+
7
+ module.exports = canProcess('sass-loader', (resolvedPath) =>
8
+ getStyleRule(/\.(scss|sass)(\.erb)?$/i, [
9
+ {
10
+ loader: resolvedPath,
11
+ options: {
12
+ sassOptions: { includePaths }
13
+ }
14
+ }
15
+ ])
16
+ )
@@ -0,0 +1,26 @@
1
+ const path = require('path')
2
+ const { canProcess } = require('../utils/helpers')
3
+ const getStyleRule = require('../utils/get_style_rule')
4
+
5
+ const {
6
+ additional_paths: paths,
7
+ source_path: sourcePath
8
+ } = require('../config')
9
+
10
+ module.exports = canProcess('stylus-loader', (resolvedPath) =>
11
+ getStyleRule(/\.(styl(us)?)(\.erb)?$/i, [
12
+ {
13
+ loader: resolvedPath,
14
+ options: {
15
+ stylusOptions: {
16
+ include: [
17
+ path.resolve(__dirname, 'node_modules'),
18
+ sourcePath,
19
+ ...paths
20
+ ]
21
+ },
22
+ sourceMap: true
23
+ }
24
+ }
25
+ ])
26
+ )
@@ -0,0 +1,37 @@
1
+ /* eslint global-require: 0 */
2
+ const { canProcess, moduleExists } = require('./helpers')
3
+ const inliningCss = require('../inliningCss')
4
+
5
+ const getStyleRule = (test, preprocessors = []) => {
6
+ if (moduleExists('css-loader')) {
7
+ const tryPostcss = () =>
8
+ canProcess('postcss-loader', (loaderPath) => ({
9
+ loader: loaderPath,
10
+ options: { sourceMap: true }
11
+ }))
12
+
13
+ // style-loader is required when using css modules with HMR on the webpack-dev-server
14
+
15
+ const use = [
16
+ inliningCss ? 'style-loader' : require('mini-css-extract-plugin').loader,
17
+ {
18
+ loader: require.resolve('css-loader'),
19
+ options: {
20
+ sourceMap: true,
21
+ importLoaders: 2
22
+ }
23
+ },
24
+ tryPostcss(),
25
+ ...preprocessors
26
+ ].filter(Boolean)
27
+
28
+ return {
29
+ test,
30
+ use
31
+ }
32
+ }
33
+
34
+ return null
35
+ }
36
+
37
+ module.exports = getStyleRule
@@ -0,0 +1,51 @@
1
+ const isArray = (value) => Array.isArray(value)
2
+ const isBoolean = (str) => /^true/.test(str) || /^false/.test(str)
3
+ const chdirTestApp = () => {
4
+ try {
5
+ return process.chdir('test/test_app')
6
+ } catch (e) {
7
+ return null
8
+ }
9
+ }
10
+
11
+ const chdirCwd = () => process.chdir(process.cwd())
12
+
13
+ const resetEnv = () => {
14
+ process.env = {}
15
+ }
16
+
17
+ const ensureTrailingSlash = (path) => (path.endsWith('/') ? path : `${path}/`)
18
+
19
+ const resolvedPath = (packageName) => {
20
+ try {
21
+ return require.resolve(packageName)
22
+ } catch (e) {
23
+ if (e.code !== 'MODULE_NOT_FOUND') {
24
+ throw e
25
+ }
26
+ return null
27
+ }
28
+ }
29
+
30
+ const moduleExists = (packageName) => (!!resolvedPath(packageName))
31
+
32
+ const canProcess = (rule, fn) => {
33
+ const modulePath = resolvedPath(rule)
34
+
35
+ if (modulePath) {
36
+ return fn(modulePath)
37
+ }
38
+
39
+ return null
40
+ }
41
+
42
+ module.exports = {
43
+ chdirTestApp,
44
+ chdirCwd,
45
+ isArray,
46
+ isBoolean,
47
+ ensureTrailingSlash,
48
+ canProcess,
49
+ moduleExists,
50
+ resetEnv
51
+ }
data/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@shakacode/shakapacker",
3
+ "version": "6.0.0-rc.6",
4
+ "description": "Use webpack to manage app-like JavaScript modules in Rails",
5
+ "main": "package/index.js",
6
+ "files": [
7
+ "package",
8
+ "lib/install/config/webpacker.yml"
9
+ ],
10
+ "engines": {
11
+ "node": "^12.13.0 || ^14 || >=16",
12
+ "yarn": ">=1 <4"
13
+ },
14
+ "peerDependencies": {
15
+ "@babel/core": "^7.15.5",
16
+ "@babel/plugin-transform-runtime": "^7.15.0",
17
+ "@babel/preset-env": "^7.15.6",
18
+ "@babel/runtime": "^7.15.4",
19
+ "babel-loader": "^8.2.2",
20
+ "compression-webpack-plugin": "^9.0.0",
21
+ "pnp-webpack-plugin": "^1.7.0",
22
+ "terser-webpack-plugin": "^5.2.4",
23
+ "webpack": "^5.53.0",
24
+ "webpack-assets-manifest": "^5.0.6",
25
+ "webpack-cli": "^4.8.0",
26
+ "webpack-merge": "^5.8.0"
27
+ },
28
+ "dependencies": {
29
+ "glob": "^7.2.0",
30
+ "js-yaml": "^4.1.0",
31
+ "path-complete-extname": "^1.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "babel-loader": "^8.2.2",
35
+ "compression-webpack-plugin": "^9.0.0",
36
+ "eslint": "^7.32.0",
37
+ "eslint-config-airbnb": "^18.2.1",
38
+ "eslint-config-prettier": "^8.3.0",
39
+ "eslint-plugin-import": "^2.24.2",
40
+ "eslint-plugin-jsx-a11y": "^6.4.1",
41
+ "eslint-plugin-react": "^7.26.0",
42
+ "jest": "^27.2.1",
43
+ "pnp-webpack-plugin": "^1.7.0",
44
+ "webpack": "^5.53.0",
45
+ "webpack-assets-manifest": "^5.0.6",
46
+ "webpack-merge": "^5.8.0"
47
+ },
48
+ "jest": {
49
+ "testRegex": "(/__tests__/.*|(\\.|/))\\.jsx?$",
50
+ "roots": [
51
+ "<rootDir>/package"
52
+ ]
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "scripts": {
58
+ "test": "jest",
59
+ "lint": "eslint package/"
60
+ },
61
+ "repository": {
62
+ "type": "git",
63
+ "url": "git+https://github.com/shakacode/shakapacker.git"
64
+ },
65
+ "author": "David Heinemeier Hansson <david@basecamp.com>, Justin Gordon <justin@shakacode.com>",
66
+ "license": "MIT",
67
+ "bugs": {
68
+ "url": "https://github.com/shakacode/shakapacker/issues"
69
+ },
70
+ "homepage": "https://github.com/shakacode/shakapacker"
71
+ }
@@ -0,0 +1,57 @@
1
+ require_relative File.join("..", "lib", "shakapacker", "utils", "version_syntax_converter")
2
+ require_relative File.join("..", "lib", "shakapacker", "utils", "git_utils")
3
+
4
+ class RaisingMessageHandler
5
+ def add_error(error)
6
+ raise error
7
+ end
8
+ end
9
+
10
+ desc("Releases both the gem and node package using the given version.
11
+
12
+ IMPORTANT: the gem version must be in valid rubygem format (no dashes).
13
+ It will be automatically converted to a valid yarn semver by the rake task
14
+ for the node package version. This only makes a difference for pre-release
15
+ versions such as `3.0.0.beta.1` (yarn version would be `3.0.0-beta.1`).
16
+
17
+ This task depends on the gem-release (ruby gem) and release-it (node package)
18
+ which are installed via `bundle install` and `yarn global add release-it`
19
+
20
+ 1st argument: The new version in rubygem format (no dashes). Pass no argument to
21
+ automatically perform a patch version bump.
22
+ 2nd argument: Perform a dry run by passing 'true' as a second argument.
23
+
24
+ Note, accept defaults for npmjs options. Script will pause to get 2FA tokens.
25
+
26
+ Example: `rake release[2.1.0,false]`")
27
+ task :release, %i[gem_version dry_run tools_install] do |_t, args|
28
+ # Check if there are uncommited changes
29
+ Shakapacker::GitUtils.uncommitted_changes?(RaisingMessageHandler.new)
30
+ args_hash = args.to_hash
31
+
32
+ is_dry_run = Shakapacker::Utils.object_to_boolean(args_hash[:dry_run])
33
+
34
+ gem_version = args_hash.fetch(:gem_version, "")
35
+
36
+ gem_root = File.expand_path("..", __dir__)
37
+
38
+ npm_version = if gem_version.strip.empty?
39
+ ""
40
+ else
41
+ Shakapacker::VersionSyntaxConverter.new.rubygem_to_npm(gem_version)
42
+ end
43
+
44
+ # See https://github.com/svenfuchs/gem-release
45
+ sh_in_dir(gem_root, "git pull --rebase")
46
+ sh_in_dir(gem_root, "gem bump --no-commit #{gem_version.strip.empty? ? '' : %(--version #{gem_version})}")
47
+
48
+ # Will bump the yarn version, commit, tag the commit, push to repo, and release on yarn
49
+ release_it_command = +"release-it"
50
+ release_it_command << " #{npm_version}" unless npm_version.strip.empty?
51
+ release_it_command << " --npm.publish --no-git.requireCleanWorkingDir"
52
+ release_it_command << " --dry-run --verbose" if is_dry_run
53
+ sh_in_dir(gem_root, release_it_command)
54
+
55
+ # Release the new gem version
56
+ sh_in_dir(gem_root, "gem release") unless is_dry_run
57
+ end
@@ -0,0 +1,109 @@
1
+ require "test_helper"
2
+
3
+ class CommandTest < Minitest::Test
4
+ def test_compile_command_returns_success_status_when_stale
5
+ Webpacker.compiler.stub :stale?, true do
6
+ Webpacker.compiler.stub :run_webpack, true do
7
+ assert_equal true, Webpacker.commands.compile
8
+ end
9
+ end
10
+ end
11
+
12
+ def test_compile_command_returns_success_status_when_fresh
13
+ Webpacker.compiler.stub :stale?, false do
14
+ Webpacker.compiler.stub :run_webpack, true do
15
+ assert_equal true, Webpacker.commands.compile
16
+ end
17
+ end
18
+ end
19
+
20
+ def test_compile_command_returns_failure_status_when_stale
21
+ Webpacker.compiler.stub :stale?, true do
22
+ Webpacker.compiler.stub :run_webpack, false do
23
+ assert_equal false, Webpacker.commands.compile
24
+ end
25
+ end
26
+ end
27
+
28
+ def test_clean_command_works_with_nested_hashes_and_without_any_compiled_files
29
+ File.stub :delete, true do
30
+ assert Webpacker.commands.clean
31
+ end
32
+ end
33
+ end
34
+
35
+ class ClearCommandVersioningTest < Minitest::Test
36
+ def setup
37
+ @now = Time.parse("2021-01-01 12:34:56 UTC")
38
+ # Test assets to be kept and deleted, path and mtime
39
+ @prev_files = {
40
+ # recent versions to be kept with Webpacker.commands.clean(count = 2)
41
+ "js/application-deadbeef.js" => @now - 4000,
42
+ "js/common-deadbeee.js" => @now - 4002,
43
+ "css/common-deadbeed.css" => @now - 4004,
44
+ "media/images/logo-deadbeeb.css" => @now - 4006,
45
+ "js/application-1eadbeef.js" => @now - 8000,
46
+ "js/common-1eadbeee.js" => @now - 8002,
47
+ "css/common-1eadbeed.css" => @now - 8004,
48
+ "media/images/logo-1eadbeeb.css" => @now - 8006,
49
+ # new files to be kept with Webpacker.commands.clean(age = 3600)
50
+ "js/brandnew-0001.js" => @now,
51
+ "js/brandnew-0002.js" => @now - 10,
52
+ "js/brandnew-0003.js" => @now - 20,
53
+ "js/brandnew-0004.js" => @now - 40,
54
+ }.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
55
+ @expired_files = {
56
+ # old files that are outside count = 2 or age = 3600 and to be deleted
57
+ "js/application-0eadbeef.js" => @now - 9000,
58
+ "js/common-0eadbeee.js" => @now - 9002,
59
+ "css/common-0eadbeed.css" => @now - 9004,
60
+ "js/brandnew-0005.js" => @now - 3640,
61
+ }.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
62
+ @all_files = @prev_files.merge(@expired_files)
63
+ @dir_glob_stub = Proc.new { |arg|
64
+ case arg
65
+ when "#{Webpacker.config.public_output_path}/**/*"
66
+ @all_files.keys
67
+ else
68
+ []
69
+ end
70
+ }
71
+ @file_mtime_stub = Proc.new { |longpath|
72
+ @all_files[longpath]
73
+ }
74
+ @file_delete_mock = Minitest::Mock.new
75
+ @expired_files.keys.each do |longpath|
76
+ @file_delete_mock.expect(:delete, 1, [longpath])
77
+ end
78
+ @file_delete_stub = Proc.new { |longpath|
79
+ if @prev_files.has_key?(longpath)
80
+ flunk "#{longpath} should not be deleted"
81
+ else
82
+ @file_delete_mock.delete(longpath)
83
+ end
84
+ }
85
+ end
86
+
87
+ def time_and_files_stub(&proc)
88
+ Time.stub :now, @now do
89
+ Dir.stub :glob, @dir_glob_stub do
90
+ File.stub :directory?, false do
91
+ File.stub :file?, true do
92
+ File.stub :mtime, @file_mtime_stub do
93
+ File.stub :delete, @file_delete_stub do
94
+ yield proc
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ @file_delete_mock.verify
102
+ end
103
+
104
+ def test_clean_command_with_versioned_files
105
+ time_and_files_stub do
106
+ assert Webpacker.commands.clean
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,68 @@
1
+ require "test_helper"
2
+
3
+ class CompilerTest < Minitest::Test
4
+ def remove_compilation_digest_path
5
+ Webpacker.compiler.send(:compilation_digest_path).tap do |path|
6
+ path.delete if path.exist?
7
+ end
8
+ end
9
+
10
+ def setup
11
+ remove_compilation_digest_path
12
+ end
13
+
14
+ def teardown
15
+ remove_compilation_digest_path
16
+ end
17
+
18
+ def test_custom_environment_variables
19
+ assert_nil Webpacker.compiler.send(:webpack_env)["FOO"]
20
+ Webpacker.compiler.env["FOO"] = "BAR"
21
+ assert Webpacker.compiler.send(:webpack_env)["FOO"] == "BAR"
22
+ ensure
23
+ Webpacker.compiler.env = {}
24
+ end
25
+
26
+ def test_freshness
27
+ assert Webpacker.compiler.stale?
28
+ assert !Webpacker.compiler.fresh?
29
+ end
30
+
31
+ def test_compile
32
+ assert !Webpacker.compiler.compile
33
+ end
34
+
35
+ def test_freshness_on_compile_success
36
+ status = OpenStruct.new(success?: true)
37
+
38
+ assert Webpacker.compiler.stale?
39
+ Open3.stub :capture3, [:sterr, :stdout, status] do
40
+ Webpacker.compiler.compile
41
+ assert Webpacker.compiler.fresh?
42
+ end
43
+ end
44
+
45
+ def test_freshness_on_compile_fail
46
+ status = OpenStruct.new(success?: false)
47
+
48
+ assert Webpacker.compiler.stale?
49
+ Open3.stub :capture3, [:sterr, :stdout, status] do
50
+ Webpacker.compiler.compile
51
+ assert Webpacker.compiler.fresh?
52
+ end
53
+ end
54
+
55
+ def test_compilation_digest_path
56
+ assert_equal Webpacker.compiler.send(:compilation_digest_path).basename.to_s, "last-compilation-digest-#{Webpacker.env}"
57
+ end
58
+
59
+ def test_external_env_variables
60
+ assert_nil Webpacker.compiler.send(:webpack_env)["WEBPACKER_ASSET_HOST"]
61
+ assert_nil Webpacker.compiler.send(:webpack_env)["WEBPACKER_RELATIVE_URL_ROOT"]
62
+
63
+ ENV["WEBPACKER_ASSET_HOST"] = "foo.bar"
64
+ ENV["WEBPACKER_RELATIVE_URL_ROOT"] = "/baz"
65
+ assert_equal Webpacker.compiler.send(:webpack_env)["WEBPACKER_ASSET_HOST"], "foo.bar"
66
+ assert_equal Webpacker.compiler.send(:webpack_env)["WEBPACKER_RELATIVE_URL_ROOT"], "/baz"
67
+ end
68
+ end
@@ -0,0 +1,78 @@
1
+ require "test_helper"
2
+
3
+ class ConfigurationTest < Webpacker::Test
4
+ def setup
5
+ @config = Webpacker::Configuration.new(
6
+ root_path: Pathname.new(File.expand_path("test_app", __dir__)),
7
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker.yml", __dir__)),
8
+ env: "production"
9
+ )
10
+ end
11
+
12
+ def test_source_path
13
+ source_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs").to_s
14
+ assert_equal source_path, @config.source_path.to_s
15
+ end
16
+
17
+ def test_source_entry_path
18
+ source_entry_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs", "entrypoints").to_s
19
+ assert_equal @config.source_entry_path.to_s, source_entry_path
20
+ end
21
+
22
+ def test_public_root_path
23
+ public_root_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public").to_s
24
+ assert_equal @config.public_path.to_s, public_root_path
25
+ end
26
+
27
+ def test_public_output_path
28
+ public_output_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs").to_s
29
+ assert_equal @config.public_output_path.to_s, public_output_path
30
+
31
+ @config = Webpacker::Configuration.new(
32
+ root_path: @config.root_path,
33
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_public_root.yml", __dir__)),
34
+ env: "production"
35
+ )
36
+
37
+ public_output_path = File.expand_path File.join(File.dirname(__FILE__), "public/packs").to_s
38
+ assert_equal @config.public_output_path.to_s, public_output_path
39
+ end
40
+
41
+ def test_public_manifest_path
42
+ public_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
43
+ assert_equal @config.public_manifest_path.to_s, public_manifest_path
44
+ end
45
+
46
+ def test_cache_path
47
+ cache_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/tmp/webpacker").to_s
48
+ assert_equal @config.cache_path.to_s, cache_path
49
+ end
50
+
51
+ def test_additional_paths
52
+ assert_equal @config.additional_paths, ["app/assets", "/etc/yarn", "some.config.js", "app/elm"]
53
+ end
54
+
55
+ def test_cache_manifest?
56
+ assert @config.cache_manifest?
57
+
58
+ with_rails_env("development") do
59
+ refute Webpacker.config.cache_manifest?
60
+ end
61
+
62
+ with_rails_env("test") do
63
+ refute Webpacker.config.cache_manifest?
64
+ end
65
+ end
66
+
67
+ def test_compile?
68
+ refute @config.compile?
69
+
70
+ with_rails_env("development") do
71
+ assert Webpacker.config.compile?
72
+ end
73
+
74
+ with_rails_env("test") do
75
+ assert Webpacker.config.compile?
76
+ end
77
+ end
78
+ end