shakapacker 6.5.5 → 6.5.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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +11 -7
- data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- data/.github/workflows/ruby.yml +3 -1
- data/.gitignore +3 -3
- data/.rspec +1 -0
- data/CHANGELOG.md +18 -2
- data/CONTRIBUTING.md +11 -1
- data/Gemfile.development_dependencies +3 -1
- data/README.md +41 -8
- data/Rakefile +4 -5
- data/gemfiles/Gemfile-rails-edge +1 -1
- data/gemfiles/Gemfile-rails.5.2.x +1 -1
- data/gemfiles/Gemfile-rails.6.0.x +1 -1
- data/gemfiles/Gemfile-rails.6.1.x +1 -1
- data/gemfiles/Gemfile-rails.7.0.x +1 -1
- data/lib/install/template.rb +21 -16
- data/lib/tasks/webpacker/compile.rake +5 -10
- data/lib/webpacker/helper.rb +20 -9
- data/lib/webpacker/version.rb +1 -1
- data/package/rules/__tests__/__utils__/webpack.js +50 -0
- data/package/rules/__tests__/babel.js +63 -0
- data/package/rules/__tests__/esbuild.js +64 -0
- data/package/rules/__tests__/index.js +0 -4
- data/package/rules/__tests__/swc.js +64 -0
- data/package/rules/babel.js +3 -14
- data/package/rules/esbuild.js +2 -13
- data/package/rules/jscommon.js +26 -0
- data/package/rules/swc.js +2 -13
- data/package/utils/helpers.js +1 -1
- data/package.json +8 -2
- data/spec/command_spec.rb +114 -0
- data/spec/compiler_spec.rb +57 -0
- data/spec/compiler_strategy_spec.rb +20 -0
- data/spec/configuration_spec.rb +281 -0
- data/{test/dev_server_runner_test.rb → spec/dev_server_runner_spec.rb} +30 -40
- data/spec/dev_server_spec.rb +45 -0
- data/spec/digest_strategy_spec.rb +33 -0
- data/{test/engine_rake_tasks_test.rb → spec/engine_rake_tasks_spec.rb} +17 -9
- data/spec/env_spec.rb +21 -0
- data/{test → spec}/fixtures/beta_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/beta_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/beta_package.json +0 -0
- data/{test → spec}/fixtures/beta_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/beta_yarn.v2.lock +0 -0
- data/{test → spec}/fixtures/git_url_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/git_url_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/git_url_package.json +0 -0
- data/{test → spec}/fixtures/git_url_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/git_url_yarn.v2.lock +0 -0
- data/{test → spec}/fixtures/github_url_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/github_url_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/github_url_package.json +0 -0
- data/{test → spec}/fixtures/github_url_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/github_url_yarn.v2.lock +0 -0
- data/{test → spec}/fixtures/relative_path_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/relative_path_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/relative_path_package.json +0 -0
- data/{test → spec}/fixtures/relative_path_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/relative_path_yarn.v2.lock +0 -0
- data/{test → spec}/fixtures/semver_caret_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/semver_caret_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/semver_caret_package.json +0 -0
- data/{test → spec}/fixtures/semver_caret_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/semver_caret_yarn.v2.lock +0 -0
- data/{test → spec}/fixtures/semver_exact_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/semver_exact_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/semver_exact_package.json +0 -0
- data/{test → spec}/fixtures/semver_exact_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/semver_exact_yarn.v2.lock +0 -0
- data/{test → spec}/fixtures/semver_tilde_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/semver_tilde_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/semver_tilde_package.json +0 -0
- data/{test → spec}/fixtures/semver_tilde_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/semver_tilde_yarn.v2.lock +0 -0
- data/{test → spec}/fixtures/without_package-lock.v1.json +0 -0
- data/{test → spec}/fixtures/without_package-lock.v2.json +0 -0
- data/{test → spec}/fixtures/without_package.json +0 -0
- data/{test → spec}/fixtures/without_yarn.v1.lock +0 -0
- data/{test → spec}/fixtures/without_yarn.v2.lock +0 -0
- data/spec/helper_spec.rb +241 -0
- data/spec/manifest_spec.rb +98 -0
- data/{test → spec}/mounted_app/Rakefile +0 -0
- data/{test → spec}/mounted_app/test/dummy/Rakefile +0 -0
- data/{test → spec}/mounted_app/test/dummy/bin/rails +0 -0
- data/{test → spec}/mounted_app/test/dummy/bin/rake +0 -0
- data/{test → spec}/mounted_app/test/dummy/config/application.rb +0 -0
- data/{test → spec}/mounted_app/test/dummy/config/environment.rb +0 -0
- data/{test → spec}/mounted_app/test/dummy/config/webpacker.yml +0 -0
- data/{test → spec}/mounted_app/test/dummy/config.ru +0 -0
- data/{test → spec}/mounted_app/test/dummy/package.json +0 -0
- data/spec/mtime_strategy_spec.rb +53 -0
- data/spec/rake_tasks_spec.rb +32 -0
- data/spec/spec_helper.rb +123 -0
- data/{test → spec}/test_app/Rakefile +0 -0
- data/{test → spec}/test_app/app/packs/entrypoints/application.js +0 -0
- data/{test → spec}/test_app/app/packs/entrypoints/generated/something.js +0 -0
- data/{test → spec}/test_app/app/packs/entrypoints/multi_entry.css +0 -0
- data/{test → spec}/test_app/app/packs/entrypoints/multi_entry.js +0 -0
- data/{test → spec}/test_app/bin/webpacker +0 -0
- data/{test → spec}/test_app/bin/webpacker-dev-server +0 -0
- data/{test → spec}/test_app/config/application.rb +0 -0
- data/{test → spec}/test_app/config/environment.rb +0 -0
- data/{test → spec}/test_app/config/initializers/inspect_autoload_paths.rb +0 -0
- data/{test → spec}/test_app/config/webpack/webpack.config.js +0 -0
- data/{test → spec}/test_app/config/webpacker.yml +0 -0
- data/{test → spec}/test_app/config/webpacker_css_extract_ignore_order_warnings.yml +0 -0
- data/{test → spec}/test_app/config/webpacker_defaults_fallback.yml +0 -0
- data/{test → spec}/test_app/config/webpacker_manifest_path.yml +0 -0
- data/{test → spec}/test_app/config/webpacker_nested_entries.yml +0 -0
- data/{test → spec}/test_app/config/webpacker_no_precompile.yml +0 -0
- data/{test → spec}/test_app/config/webpacker_other_location.yml +0 -0
- data/{test → spec}/test_app/config/webpacker_public_root.yml +0 -0
- data/{test → spec}/test_app/config.ru +0 -0
- data/{test → spec}/test_app/package.json +0 -0
- data/{test → spec}/test_app/public/packs/manifest.json +8 -0
- data/{test → spec}/test_app/some.config.js +0 -0
- data/{test → spec}/test_app/yarn.lock +0 -0
- data/spec/version_checker_spec.rb +950 -0
- data/{test/webpack_runner_test.rb → spec/webpack_runner_spec.rb} +12 -15
- data/spec/webpacker_spec.rb +39 -0
- data/yarn.lock +846 -844
- metadata +102 -187
- data/.github/ISSUE_TEMPLATE/feature-request.md +0 -18
- data/lib/tasks/yarn.rake +0 -44
- data/test/command_test.rb +0 -109
- data/test/compiler_strategy_test.rb +0 -27
- data/test/compiler_test.rb +0 -60
- data/test/configuration_test.rb +0 -186
- data/test/dev_server_test.rb +0 -47
- data/test/digest_strategy_test.rb +0 -33
- data/test/env_test.rb +0 -23
- data/test/helper_test.rb +0 -248
- data/test/manifest_test.rb +0 -89
- data/test/mtime_strategy_test.rb +0 -42
- data/test/rake_tasks_test.rb +0 -37
- data/test/test_helper.rb +0 -33
- data/test/version_checker_test.rb +0 -826
- data/test/webpacker_test.rb +0 -49
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const {
|
|
3
|
+
app_javascript,
|
|
4
|
+
node_modules,
|
|
5
|
+
node_modules_included,
|
|
6
|
+
createTestCompiler,
|
|
7
|
+
createTrackLoader,
|
|
8
|
+
} = require("./__utils__/webpack");
|
|
9
|
+
const swcConfig = require("../swc");
|
|
10
|
+
|
|
11
|
+
jest.mock("../../config", () => {
|
|
12
|
+
const original = jest.requireActual("../../config");
|
|
13
|
+
return {
|
|
14
|
+
...original,
|
|
15
|
+
webpack_loader: "swc",
|
|
16
|
+
additional_paths: [...original.additional_paths, "node_modules/included"],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const createWebpackConfig = (file, use) => {
|
|
21
|
+
return {
|
|
22
|
+
entry: { file },
|
|
23
|
+
module: {
|
|
24
|
+
rules: [
|
|
25
|
+
{
|
|
26
|
+
...swcConfig,
|
|
27
|
+
use,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
output: {
|
|
32
|
+
path: "/",
|
|
33
|
+
filename: "scripts-bundled.js",
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
describe("swc", () => {
|
|
39
|
+
test("process source path", async () => {
|
|
40
|
+
const normalPath = `${app_javascript}/a.js`;
|
|
41
|
+
const [tracked, loader] = createTrackLoader();
|
|
42
|
+
const compiler = createTestCompiler(
|
|
43
|
+
createWebpackConfig(normalPath, loader)
|
|
44
|
+
);
|
|
45
|
+
await compiler.run();
|
|
46
|
+
expect(tracked[normalPath]).toBeTruthy();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("exclude node_modules", async () => {
|
|
50
|
+
const ignored = `${node_modules}/a.js`;
|
|
51
|
+
const [tracked, loader] = createTrackLoader();
|
|
52
|
+
const compiler = createTestCompiler(createWebpackConfig(ignored, loader));
|
|
53
|
+
await compiler.run();
|
|
54
|
+
expect(tracked[ignored]).toBeUndefined();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("explicitly included node_modules should be transpiled", async () => {
|
|
58
|
+
const included = `${node_modules_included}/a.js`;
|
|
59
|
+
const [tracked, loader] = createTrackLoader();
|
|
60
|
+
const compiler = createTestCompiler(createWebpackConfig(included, loader));
|
|
61
|
+
await compiler.run();
|
|
62
|
+
expect(tracked[included]).toBeTruthy();
|
|
63
|
+
});
|
|
64
|
+
});
|
data/package/rules/babel.js
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
|
-
const { resolve } = require('path')
|
|
2
|
-
const { realpathSync } = require('fs')
|
|
3
1
|
const { loaderMatches } = require('../utils/helpers')
|
|
4
|
-
|
|
5
2
|
const {
|
|
6
|
-
source_path: sourcePath,
|
|
7
|
-
additional_paths: additionalPaths,
|
|
8
3
|
webpack_loader: webpackLoader
|
|
9
4
|
} = require('../config')
|
|
10
5
|
const { isProduction } = require('../env')
|
|
6
|
+
const jscommon = require('./jscommon')
|
|
11
7
|
|
|
12
8
|
module.exports = loaderMatches(webpackLoader, 'babel', () => ({
|
|
13
9
|
test: /\.(js|jsx|mjs|ts|tsx|coffee)?(\.erb)?$/,
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
return realpathSync(p)
|
|
17
|
-
} catch (e) {
|
|
18
|
-
return resolve(p)
|
|
19
|
-
}
|
|
20
|
-
}),
|
|
21
|
-
exclude: /node_modules/,
|
|
10
|
+
...jscommon,
|
|
22
11
|
use: [
|
|
23
12
|
{
|
|
24
13
|
loader: require.resolve('babel-loader'),
|
|
@@ -29,4 +18,4 @@ module.exports = loaderMatches(webpackLoader, 'babel', () => ({
|
|
|
29
18
|
}
|
|
30
19
|
}
|
|
31
20
|
]
|
|
32
|
-
|
|
21
|
+
}))
|
data/package/rules/esbuild.js
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
|
-
const { resolve } = require('path')
|
|
2
|
-
const { realpathSync } = require('fs')
|
|
3
1
|
const { loaderMatches } = require('../utils/helpers')
|
|
4
2
|
const { getEsbuildLoaderConfig } = require('../esbuild')
|
|
5
|
-
|
|
6
3
|
const {
|
|
7
|
-
source_path: sourcePath,
|
|
8
|
-
additional_paths: additionalPaths,
|
|
9
4
|
webpack_loader: webpackLoader
|
|
10
5
|
} = require('../config')
|
|
6
|
+
const jscommon = require('./jscommon')
|
|
11
7
|
|
|
12
8
|
module.exports = loaderMatches(webpackLoader, 'esbuild', () => ({
|
|
13
9
|
test: /\.(ts|tsx|js|jsx|mjs|coffee)?(\.erb)?$/,
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
return realpathSync(p)
|
|
17
|
-
} catch (e) {
|
|
18
|
-
return resolve(p)
|
|
19
|
-
}
|
|
20
|
-
}),
|
|
21
|
-
exclude: /node_modules/,
|
|
10
|
+
...jscommon,
|
|
22
11
|
use: ({ resource }) => getEsbuildLoaderConfig(resource)
|
|
23
12
|
}))
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const { resolve } = require('path')
|
|
2
|
+
const { realpathSync } = require('fs')
|
|
3
|
+
const {
|
|
4
|
+
source_path: sourcePath,
|
|
5
|
+
additional_paths: additionalPaths
|
|
6
|
+
} = require('../config')
|
|
7
|
+
|
|
8
|
+
const inclusions = [sourcePath, ...additionalPaths].map(p => {
|
|
9
|
+
try {
|
|
10
|
+
return realpathSync(p)
|
|
11
|
+
} catch (e) {
|
|
12
|
+
return resolve(p)
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
include: inclusions,
|
|
18
|
+
exclude: [
|
|
19
|
+
{
|
|
20
|
+
// exclude all node_modules from running through babel-loader
|
|
21
|
+
and: [resolve('node_modules')],
|
|
22
|
+
// Do not exclude inclusions, as otherwise these won't be transpiled
|
|
23
|
+
not: [...inclusions]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
data/package/rules/swc.js
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
|
-
const { resolve } = require('path')
|
|
2
|
-
const { realpathSync } = require('fs')
|
|
3
1
|
const { loaderMatches } = require('../utils/helpers')
|
|
4
2
|
const { getSwcLoaderConfig } = require('../swc')
|
|
5
|
-
|
|
6
3
|
const {
|
|
7
|
-
source_path: sourcePath,
|
|
8
|
-
additional_paths: additionalPaths,
|
|
9
4
|
webpack_loader: webpackLoader
|
|
10
5
|
} = require('../config')
|
|
6
|
+
const jscommon = require('./jscommon')
|
|
11
7
|
|
|
12
8
|
module.exports = loaderMatches(webpackLoader, 'swc', () => ({
|
|
13
9
|
test: /\.(ts|tsx|js|jsx|mjs|coffee)?(\.erb)?$/,
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
return realpathSync(p)
|
|
17
|
-
} catch (e) {
|
|
18
|
-
return resolve(p)
|
|
19
|
-
}
|
|
20
|
-
}),
|
|
21
|
-
exclude: /node_modules/,
|
|
10
|
+
...jscommon,
|
|
22
11
|
use: ({ resource }) => getSwcLoaderConfig(resource)
|
|
23
12
|
}))
|
data/package/utils/helpers.js
CHANGED
|
@@ -2,7 +2,7 @@ const isArray = (value) => Array.isArray(value)
|
|
|
2
2
|
const isBoolean = (str) => /^true/.test(str) || /^false/.test(str)
|
|
3
3
|
const chdirTestApp = () => {
|
|
4
4
|
try {
|
|
5
|
-
return process.chdir('
|
|
5
|
+
return process.chdir('spec/test_app')
|
|
6
6
|
} catch (e) {
|
|
7
7
|
return null
|
|
8
8
|
}
|
data/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shakapacker",
|
|
3
|
-
"version": "6.5.
|
|
3
|
+
"version": "6.5.6",
|
|
4
4
|
"description": "Use webpack to manage app-like JavaScript modules in Rails",
|
|
5
5
|
"main": "package/index.js",
|
|
6
6
|
"files": [
|
|
@@ -40,14 +40,20 @@
|
|
|
40
40
|
"eslint-plugin-import": "^2.24.2",
|
|
41
41
|
"eslint-plugin-jsx-a11y": "^6.4.1",
|
|
42
42
|
"eslint-plugin-react": "^7.26.0",
|
|
43
|
-
"jest": "^
|
|
43
|
+
"jest": "^28.1.3",
|
|
44
|
+
"memory-fs": "^0.5.0",
|
|
44
45
|
"swc-loader": "^0.1.15",
|
|
46
|
+
"thenify": "^3.3.1",
|
|
45
47
|
"webpack": "^5.72.0",
|
|
46
48
|
"webpack-assets-manifest": "^5.0.6",
|
|
47
49
|
"webpack-merge": "^5.8.0"
|
|
48
50
|
},
|
|
49
51
|
"jest": {
|
|
50
52
|
"testRegex": "(/__tests__/.*|(\\.|/))\\.jsx?$",
|
|
53
|
+
"testPathIgnorePatterns": [
|
|
54
|
+
"/__fixtures__/",
|
|
55
|
+
"/__utils__/"
|
|
56
|
+
],
|
|
51
57
|
"roots": [
|
|
52
58
|
"<rootDir>/package"
|
|
53
59
|
]
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
describe "Command" do
|
|
2
|
+
before do
|
|
3
|
+
allow(Webpacker.logger).to receive(:info)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
describe "#compile" do
|
|
7
|
+
it "returns success status when stale" do
|
|
8
|
+
expect(Webpacker.compiler).to receive(:stale?).and_return(true)
|
|
9
|
+
expect(Webpacker.compiler).to receive(:run_webpack).and_return(true)
|
|
10
|
+
|
|
11
|
+
expect(Webpacker.commands.compile).to be true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "returns success status when fresh" do
|
|
15
|
+
expect(Webpacker.compiler).to receive(:stale?).and_return(false)
|
|
16
|
+
|
|
17
|
+
expect(Webpacker.commands.compile).to be true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "returns failure status when stale" do
|
|
21
|
+
expect(Webpacker.compiler).to receive(:stale?).and_return(true)
|
|
22
|
+
expect(Webpacker.compiler).to receive(:run_webpack).and_return(false)
|
|
23
|
+
|
|
24
|
+
expect(Webpacker.commands.compile).to be false
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#clean" do
|
|
29
|
+
let(:now) { Time.parse("2021-01-01 12:34:56 UTC") }
|
|
30
|
+
let(:prev_files) do
|
|
31
|
+
# Test assets to be kept and deleted, path and mtime
|
|
32
|
+
{
|
|
33
|
+
# recent versions to be kept with Webpacker.commands.clean(count = 2)
|
|
34
|
+
"js/application-deadbeef.js" => now - 4000,
|
|
35
|
+
"js/common-deadbeee.js" => now - 4002,
|
|
36
|
+
"css/common-deadbeed.css" => now - 4004,
|
|
37
|
+
"media/images/logo-deadbeeb.css" => now - 4006,
|
|
38
|
+
"js/application-1eadbeef.js" => now - 8000,
|
|
39
|
+
"js/common-1eadbeee.js" => now - 8002,
|
|
40
|
+
"css/common-1eadbeed.css" => now - 8004,
|
|
41
|
+
"media/images/logo-1eadbeeb.css" => now - 8006,
|
|
42
|
+
# new files to be kept with Webpacker.commands.clean(age = 3600)
|
|
43
|
+
"js/brandnew-0001.js" => now,
|
|
44
|
+
"js/brandnew-0002.js" => now - 10,
|
|
45
|
+
"js/brandnew-0003.js" => now - 20,
|
|
46
|
+
"js/brandnew-0004.js" => now - 40,
|
|
47
|
+
}.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
let(:expired_files) do
|
|
51
|
+
{
|
|
52
|
+
# old files that are outside count = 2 or age = 3600 and to be deleted
|
|
53
|
+
"js/application-0eadbeef.js" => now - 9000,
|
|
54
|
+
"js/common-0eadbeee.js" => now - 9002,
|
|
55
|
+
"css/common-0eadbeed.css" => now - 9004,
|
|
56
|
+
"js/brandnew-0005.js" => now - 3640,
|
|
57
|
+
}.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
let(:all_files) { prev_files.merge(expired_files) }
|
|
61
|
+
|
|
62
|
+
let(:file_delete_mock) { double("File Delete") }
|
|
63
|
+
let(:file_mtime_stub) { Proc.new { |longpath| all_files[longpath] } }
|
|
64
|
+
let(:file_delete_stub) { Proc.new { |longpath| file_delete_mock.delete(longpath) } }
|
|
65
|
+
|
|
66
|
+
before :context do
|
|
67
|
+
@dir_glob_stub = Proc.new { |arg|
|
|
68
|
+
case arg
|
|
69
|
+
when "#{Webpacker.config.public_output_path}/**/*"
|
|
70
|
+
all_files.keys
|
|
71
|
+
else
|
|
72
|
+
[]
|
|
73
|
+
end
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "works with nested hashes and without any compiled files" do
|
|
78
|
+
allow(File).to receive(:delete).and_return(true)
|
|
79
|
+
expect(Webpacker.commands.clean).to be true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "deletes only and only expired versioned files if no parameter passed" do
|
|
83
|
+
all_files.keys.each do |longpath|
|
|
84
|
+
allow(file_delete_mock).to receive(:delete).with(longpath)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
with_time_dir_and_files_stub do
|
|
88
|
+
expect(Webpacker.commands.clean).to be true
|
|
89
|
+
|
|
90
|
+
# Verify that only and only expired files are deleted
|
|
91
|
+
all_files.keys.each do |longpath|
|
|
92
|
+
if expired_files.has_key? longpath
|
|
93
|
+
expect(file_delete_mock).to have_received(:delete).with(longpath)
|
|
94
|
+
else
|
|
95
|
+
expect(file_delete_mock).to_not have_received(:delete).with(longpath)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
def with_time_dir_and_files_stub(&proc)
|
|
104
|
+
allow(Time).to receive(:now).and_return(now)
|
|
105
|
+
allow(Dir).to receive(:glob) { |arg| @dir_glob_stub.call(arg) }
|
|
106
|
+
allow(File).to receive(:directory?).and_return(false)
|
|
107
|
+
allow(File).to receive(:file?).and_return(true)
|
|
108
|
+
allow(File).to receive(:mtime) { |arg| file_mtime_stub.call(arg) }
|
|
109
|
+
allow(File).to receive(:delete) { |arg| file_delete_stub.call(arg) }
|
|
110
|
+
|
|
111
|
+
yield proc
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
describe "Webpacker::Compiler" do
|
|
2
|
+
it "accepts custom environment variables" do
|
|
3
|
+
expect(Webpacker.compiler.send(:webpack_env)["FOO"]).to be nil
|
|
4
|
+
|
|
5
|
+
Webpacker.compiler.env["FOO"] = "BAR"
|
|
6
|
+
expect(Webpacker.compiler.send(:webpack_env)["FOO"]).to eq "BAR"
|
|
7
|
+
ensure
|
|
8
|
+
Webpacker.compiler.env = {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "returns true when fresh" do
|
|
12
|
+
mocked_strategy = double("Strategy")
|
|
13
|
+
expect(mocked_strategy).to receive(:stale?).and_return(false)
|
|
14
|
+
|
|
15
|
+
expect(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
|
|
16
|
+
|
|
17
|
+
expect(Webpacker.compiler.compile).to be true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "returns true and calls after_compile_hook on successful compile" do
|
|
21
|
+
mocked_strategy = spy("Strategy")
|
|
22
|
+
expect(mocked_strategy).to receive(:stale?).and_return(true)
|
|
23
|
+
|
|
24
|
+
allow(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
|
|
25
|
+
|
|
26
|
+
status = OpenStruct.new(success?: true)
|
|
27
|
+
allow(Open3).to receive(:capture3).and_return([:sterr, :stdout, status])
|
|
28
|
+
|
|
29
|
+
expect(Webpacker.compiler.compile).to be true
|
|
30
|
+
expect(mocked_strategy).to have_received(:after_compile_hook)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "returns false and calls after_compile_hook on failed compile" do
|
|
34
|
+
mocked_strategy = spy("Strategy")
|
|
35
|
+
allow(mocked_strategy).to receive(:stale?).and_return(true)
|
|
36
|
+
allow(mocked_strategy).to receive(:after_compile_hook)
|
|
37
|
+
|
|
38
|
+
allow(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
|
|
39
|
+
|
|
40
|
+
status = OpenStruct.new(success?: false)
|
|
41
|
+
allow(Open3).to receive(:capture3).and_return([:sterr, :stdout, status])
|
|
42
|
+
|
|
43
|
+
expect(Webpacker.compiler.compile).to be false
|
|
44
|
+
expect(mocked_strategy).to have_received(:after_compile_hook)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "accepts external env variables" do
|
|
48
|
+
expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_ASSET_HOST"]).to be nil
|
|
49
|
+
expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_RELATIVE_URL_ROOT"]).to be nil
|
|
50
|
+
|
|
51
|
+
ENV["WEBPACKER_ASSET_HOST"] = "foo.bar"
|
|
52
|
+
ENV["WEBPACKER_RELATIVE_URL_ROOT"] = "/baz"
|
|
53
|
+
|
|
54
|
+
expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_ASSET_HOST"]).to eq "foo.bar"
|
|
55
|
+
expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_RELATIVE_URL_ROOT"]).to eq "/baz"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
describe "Webpacker::CompilerStrategy" do
|
|
2
|
+
describe "#from_config" do
|
|
3
|
+
it "returns and instance of MtimeStrategy when compiler_strategy is set to mtime" do
|
|
4
|
+
allow(Webpacker.config).to receive(:compiler_strategy).and_return("mtime")
|
|
5
|
+
expect(Webpacker::CompilerStrategy.from_config).to be_an_instance_of(Webpacker::MtimeStrategy)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "returns and instance of DigestStrategy when compiler_strategy is set to digest" do
|
|
9
|
+
allow(Webpacker.config).to receive(:compiler_strategy).and_return("digest")
|
|
10
|
+
expect(Webpacker::CompilerStrategy.from_config).to be_an_instance_of(Webpacker::DigestStrategy)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "raise exception for unknown compiler_strategy in the config file" do
|
|
14
|
+
expected_error_message = "Unknown strategy 'other'. Available options are 'mtime' and 'digest'."
|
|
15
|
+
allow(Webpacker.config).to receive(:compiler_strategy).and_return("other")
|
|
16
|
+
|
|
17
|
+
expect { Webpacker::CompilerStrategy.from_config }.to raise_error(expected_error_message)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
describe "Webpacker::Configuration" do
|
|
2
|
+
ROOT_PATH = Pathname.new(File.expand_path("test_app", __dir__))
|
|
3
|
+
|
|
4
|
+
context "with standard webpacker.yml" do
|
|
5
|
+
let(:config) do
|
|
6
|
+
Webpacker::Configuration.new(
|
|
7
|
+
root_path: ROOT_PATH,
|
|
8
|
+
config_path: Pathname.new(File.expand_path("./test_app/config/webpacker.yml", __dir__)),
|
|
9
|
+
env: "production"
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "#source_path returns correct path" do
|
|
14
|
+
source_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs").to_s
|
|
15
|
+
expect(config.source_path.to_s).to eq source_path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "#source_entry_path returns correct path" do
|
|
19
|
+
source_entry_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs", "entrypoints").to_s
|
|
20
|
+
expect(config.source_entry_path.to_s).to eq source_entry_path
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "#public_root_path returns correct path" do
|
|
24
|
+
public_root_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public").to_s
|
|
25
|
+
expect(config.public_path.to_s).to eq public_root_path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "#public_output_path returns correct path" do
|
|
29
|
+
public_output_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs").to_s
|
|
30
|
+
expect(config.public_output_path.to_s).to eq public_output_path
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "#public_manifest_path returns correct path" do
|
|
34
|
+
public_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
|
|
35
|
+
expect(config.public_manifest_path.to_s).to eq public_manifest_path
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "#manifest_path returns correct path" do
|
|
39
|
+
manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
|
|
40
|
+
expect(config.manifest_path.to_s).to eq manifest_path
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "#cache_path returns correct path" do
|
|
44
|
+
cache_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/tmp/webpacker").to_s
|
|
45
|
+
expect(config.cache_path.to_s).to eq cache_path
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "#additional_paths returns correct path" do
|
|
49
|
+
expect(config.additional_paths).to eq ["app/assets", "/etc/yarn", "some.config.js", "app/elm"]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#cache_manifest?" do
|
|
53
|
+
it "returns true in production environment" do
|
|
54
|
+
expect(config.cache_manifest?).to be true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "returns false in developemnt environemnt" do
|
|
58
|
+
with_rails_env("development") do
|
|
59
|
+
expect(Webpacker.config.cache_manifest?).to be false
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "returns false in test environment" do
|
|
64
|
+
with_rails_env("test") do
|
|
65
|
+
expect(Webpacker.config.cache_manifest?).to be false
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "#compile?" do
|
|
71
|
+
it "returns false in production environment" do
|
|
72
|
+
expect(config.compile?).to be false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "returns true in developemnt environemnt" do
|
|
76
|
+
with_rails_env("development") do
|
|
77
|
+
expect(Webpacker.config.compile?).to be true
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "returns true in test environemnt" do
|
|
82
|
+
with_rails_env("test") do
|
|
83
|
+
expect(Webpacker.config.compile?).to be true
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe "#nested_entries?" do
|
|
89
|
+
it "returns false in production environment" do
|
|
90
|
+
expect(config.nested_entries?).to be false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "returns false in development environment" do
|
|
94
|
+
with_rails_env("development") do
|
|
95
|
+
expect(Webpacker.config.nested_entries?).to be false
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "returns false in test environment" do
|
|
100
|
+
with_rails_env("test") do
|
|
101
|
+
expect(Webpacker.config.nested_entries?).to be false
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe "#ensure_consistent_versioning?" do
|
|
107
|
+
it "returns false in production environment" do
|
|
108
|
+
expect(config.ensure_consistent_versioning?).to be false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "returns true in development environment" do
|
|
112
|
+
with_rails_env("development") do
|
|
113
|
+
expect(Webpacker.config.ensure_consistent_versioning?).to be true
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "returns false in test environment" do
|
|
118
|
+
with_rails_env("test") do
|
|
119
|
+
expect(Webpacker.config.ensure_consistent_versioning?).to be false
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
describe "#webpacker_precompile?" do
|
|
125
|
+
before :each do
|
|
126
|
+
ENV["WEBPACKER_PRECOMPILE"] = nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
subject { config.webpacker_precompile? }
|
|
130
|
+
|
|
131
|
+
it "returns true when WEBPACKER_PRECOMPILE is unset" do
|
|
132
|
+
is_expected.to be true
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "returns false when WEBPACKER_PRECOMPILE sets to no" do
|
|
136
|
+
ENV["WEBPACKER_PRECOMPILE"] = "no"
|
|
137
|
+
is_expected.to be false
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "returns true when WEBPACKER_PRECOMPILE sets to yes" do
|
|
141
|
+
ENV["WEBPACKER_PRECOMPILE"] = "yes"
|
|
142
|
+
is_expected.to be true
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "returns false when WEBPACKER_PRECOMPILE sets to false" do
|
|
146
|
+
ENV["WEBPACKER_PRECOMPILE"] = "false"
|
|
147
|
+
is_expected.to be false
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "returns true when WEBPACKER_PRECOMPILE sets to true" do
|
|
151
|
+
ENV["WEBPACKER_PRECOMPILE"] = "true"
|
|
152
|
+
is_expected.to be true
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "returns false when WEBPACKER_PRECOMPILE sets to n" do
|
|
156
|
+
ENV["WEBPACKER_PRECOMPILE"] = "n"
|
|
157
|
+
is_expected.to be false
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "returns true when WEBPACKER_PRECOMPILE sets to y" do
|
|
161
|
+
ENV["WEBPACKER_PRECOMPILE"] = "y"
|
|
162
|
+
is_expected.to be true
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "returns false when WEBPACKER_PRECOMPILE sets to f" do
|
|
166
|
+
ENV["WEBPACKER_PRECOMPILE"] = "f"
|
|
167
|
+
is_expected.to be false
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "returns true when WEBPACKER_PRECOMPILE sets to t" do
|
|
171
|
+
ENV["WEBPACKER_PRECOMPILE"] = "t"
|
|
172
|
+
is_expected.to be true
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
context "with webpacker config file containing public_output_path entry" do
|
|
178
|
+
config = Webpacker::Configuration.new(
|
|
179
|
+
root_path: ROOT_PATH,
|
|
180
|
+
config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_public_root.yml", __dir__)),
|
|
181
|
+
env: "production"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
it "#public_output_path returns correct path" do
|
|
185
|
+
expected_public_output_path = File.expand_path File.join(File.dirname(__FILE__), "public/packs").to_s
|
|
186
|
+
expect(config.public_output_path.to_s).to eq expected_public_output_path
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
context "with webpacker config file containing manifext_path entry" do
|
|
191
|
+
config = Webpacker::Configuration.new(
|
|
192
|
+
root_path: ROOT_PATH,
|
|
193
|
+
config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_manifest_path.yml", __dir__)),
|
|
194
|
+
env: "production"
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
it "#manifest_path returns correct expected value" do
|
|
198
|
+
expected_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs", "manifest.json").to_s
|
|
199
|
+
expect(config.manifest_path.to_s).to eq expected_manifest_path
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
context "with webpacker_precompile entry set to false" do
|
|
204
|
+
describe "#webpacker_precompile?" do
|
|
205
|
+
before :each do
|
|
206
|
+
ENV["WEBPACKER_PRECOMPILE"] = nil
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
let(:config) {
|
|
210
|
+
Webpacker::Configuration.new(
|
|
211
|
+
root_path: ROOT_PATH,
|
|
212
|
+
config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_no_precompile.yml", __dir__)),
|
|
213
|
+
env: "production"
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
subject { config.webpacker_precompile? }
|
|
218
|
+
|
|
219
|
+
it "returns false with unset WEBPACKER_PRECOMPILE" do
|
|
220
|
+
expect(subject).to be false
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "returns true with WEBPACKER_PRECOMPILE set to true" do
|
|
224
|
+
ENV["WEBPACKER_PRECOMPILE"] = "true"
|
|
225
|
+
expect(subject).to be true
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "returns false with WEBPACKER_PRECOMPILE set to nil" do
|
|
229
|
+
ENV["WEBPACKER_PRECOMPILE"] = nil
|
|
230
|
+
expect(subject).to be false
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
context "with webpacker config file containing invalid path" do
|
|
236
|
+
config = Webpacker::Configuration.new(
|
|
237
|
+
root_path: ROOT_PATH,
|
|
238
|
+
config_path: Pathname.new(File.expand_path("./test_app/config/invalid_path.yml", __dir__)),
|
|
239
|
+
env: "default"
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
it "#webpacker_precompile? returns false" do
|
|
243
|
+
expect(config.webpacker_precompile?).to be false
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
context "with webpacker config file with defaults fallback" do
|
|
248
|
+
let(:config) do
|
|
249
|
+
Webpacker::Configuration.new(
|
|
250
|
+
root_path: ROOT_PATH,
|
|
251
|
+
config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_defaults_fallback.yml", __dir__)),
|
|
252
|
+
env: "default"
|
|
253
|
+
)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "#cache_manifest? falls back to 'default' config from bundled file" do
|
|
257
|
+
expect(config.cache_manifest?).to be false
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "#webpacker_precompile? uses 'default' config from custom file" do
|
|
261
|
+
expect(config.webpacker_precompile?).to be false
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
context "falls back to bundled production config for custom environments" do
|
|
266
|
+
let(:config) do
|
|
267
|
+
Webpacker::Configuration.new(
|
|
268
|
+
root_path: ROOT_PATH,
|
|
269
|
+
config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_defaults_fallback.yml", __dir__)),
|
|
270
|
+
env: "staging"
|
|
271
|
+
)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "#cache_manifest? fall back to 'production' config from bundled file" do
|
|
275
|
+
expect(config.cache_manifest?).to be true
|
|
276
|
+
end
|
|
277
|
+
it "#webpacker_precompile? use 'staging' config from custom file" do
|
|
278
|
+
expect(config.webpacker_precompile?).to be false
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|