shakapacker 6.0.0.rc.6

Sign up to get free protection for your applications and to get access to all the features.
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