webpacker 3.1.1 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -0
- data/Gemfile.lock +17 -18
- data/README.md +21 -0
- data/docs/css.md +8 -3
- data/docs/troubleshooting.md +18 -0
- data/docs/webpack.md +30 -3
- data/lib/install/angular.rb +12 -0
- data/lib/install/coffee.rb +22 -0
- data/lib/install/config/.postcssrc.yml +1 -1
- data/lib/install/elm.rb +12 -0
- data/lib/install/erb.rb +22 -0
- data/lib/install/examples/coffee/hello_coffee.coffee +4 -0
- data/lib/install/examples/erb/hello_erb.js.erb +6 -0
- data/{package/rules → lib/install/loaders}/coffee.js +0 -0
- data/{package/rules → lib/install/loaders}/elm.js +0 -0
- data/{package/rules → lib/install/loaders}/erb.js +0 -0
- data/{package/rules → lib/install/loaders}/typescript.js +0 -0
- data/{package/rules → lib/install/loaders}/vue.js +1 -1
- data/lib/install/vue.rb +12 -0
- data/lib/tasks/installers.rake +3 -1
- data/lib/tasks/webpacker.rake +3 -1
- data/lib/tasks/webpacker/check_node.rake +2 -6
- data/lib/webpacker/compiler.rb +6 -1
- data/lib/webpacker/configuration.rb +8 -0
- data/lib/webpacker/helper.rb +14 -2
- data/lib/webpacker/version.rb +1 -1
- data/package.json +4 -10
- data/package/__tests__/environment.js +74 -0
- data/package/config.js +3 -0
- data/package/config_types/config_list.js +2 -0
- data/package/environment.js +6 -9
- data/package/environments/development.js +3 -4
- data/package/index.js +1 -2
- data/package/rules/file.js +1 -3
- data/package/rules/index.js +0 -12
- data/test/compiler_test.rb +11 -0
- data/test/configuration_test.rb +8 -0
- data/test/helper_test.rb +8 -0
- data/test/test_app/app/javascript/packs/application.js +10 -0
- data/test/test_app/config/webpacker.yml +65 -0
- data/test/test_helper.rb +1 -1
- data/yarn.lock +100 -188
- metadata +16 -9
- data/package/asset_host.js +0 -20
- data/package/rules/url.js +0 -13
data/lib/tasks/installers.rake
CHANGED
data/lib/tasks/webpacker.rake
CHANGED
@@ -10,7 +10,9 @@ tasks = {
|
|
10
10
|
"webpacker:install:react" => "Installs and setup example React component",
|
11
11
|
"webpacker:install:vue" => "Installs and setup example Vue component",
|
12
12
|
"webpacker:install:angular" => "Installs and setup example Angular component",
|
13
|
-
"webpacker:install:elm" => "Installs and setup example Elm component"
|
13
|
+
"webpacker:install:elm" => "Installs and setup example Elm component",
|
14
|
+
"webpacker:install:erb" => "Installs Erb loader with an example",
|
15
|
+
"webpacker:install:coffee" => "Installs CoffeeScript loader with an example"
|
14
16
|
}.freeze
|
15
17
|
|
16
18
|
desc "Lists all available tasks in Webpacker"
|
@@ -2,12 +2,8 @@ namespace :webpacker do
|
|
2
2
|
desc "Verifies if Node.js is installed"
|
3
3
|
task :check_node do
|
4
4
|
begin
|
5
|
-
|
6
|
-
|
7
|
-
rescue Errno::ENOENT
|
8
|
-
node_version = `nodejs -v`
|
9
|
-
raise Errno::ENOENT if node_version.blank?
|
10
|
-
end
|
5
|
+
node_version = `node -v || nodejs -v`
|
6
|
+
raise Errno::ENOENT if node_version.blank?
|
11
7
|
|
12
8
|
pkg_path = Pathname.new("#{__dir__}/../../../package.json").realpath
|
13
9
|
node_requirement = JSON.parse(pkg_path.read)["engines"]["node"]
|
data/lib/webpacker/compiler.rb
CHANGED
@@ -65,7 +65,12 @@ class Webpacker::Compiler
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def default_watched_paths
|
68
|
-
[
|
68
|
+
[
|
69
|
+
*config.resolved_paths_globbed,
|
70
|
+
"#{config.source_path.relative_path_from(Rails.root)}/**/*",
|
71
|
+
"yarn.lock", "package.json",
|
72
|
+
"config/webpack/**/*"
|
73
|
+
].freeze
|
69
74
|
end
|
70
75
|
|
71
76
|
def compilation_digest_path
|
@@ -21,6 +21,14 @@ class Webpacker::Configuration
|
|
21
21
|
root_path.join(fetch(:source_path))
|
22
22
|
end
|
23
23
|
|
24
|
+
def resolved_paths
|
25
|
+
fetch(:resolved_paths)
|
26
|
+
end
|
27
|
+
|
28
|
+
def resolved_paths_globbed
|
29
|
+
resolved_paths.map { |p| "#{p}/**/*" }
|
30
|
+
end
|
31
|
+
|
24
32
|
def source_entry_path
|
25
33
|
source_path.join(fetch(:source_entry_path))
|
26
34
|
end
|
data/lib/webpacker/helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Webpacker::Helper
|
2
|
-
# Computes the
|
3
|
-
# Return relative path using manifest.json and passes it to
|
2
|
+
# Computes the relative path for a given Webpacker asset.
|
3
|
+
# Return relative path using manifest.json and passes it to asset_path helper
|
4
4
|
# This will use asset_path internally, so most of their behaviors will be the same.
|
5
5
|
#
|
6
6
|
# Example:
|
@@ -9,6 +9,18 @@ module Webpacker::Helper
|
|
9
9
|
def asset_pack_path(name, **options)
|
10
10
|
asset_path(Webpacker.manifest.lookup!(name), **options)
|
11
11
|
end
|
12
|
+
|
13
|
+
# Computes the absolute path for a given Webpacker asset.
|
14
|
+
# Return absolute path using manifest.json and passes it to asset_url helper
|
15
|
+
# This will use asset_url internally, so most of their behaviors will be the same.
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
#
|
19
|
+
# <%= asset_pack_url 'calendar.css' %> # => "http://example.com/packs/calendar-1016838bab065ae1e122.css"
|
20
|
+
def asset_pack_url(name, **options)
|
21
|
+
asset_url(Webpacker.manifest.lookup!(name), **options)
|
22
|
+
end
|
23
|
+
|
12
24
|
# Creates a script tag that references the named pack file, as compiled by webpack per the entries list
|
13
25
|
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
|
14
26
|
# app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
|
data/lib/webpacker/version.rb
CHANGED
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@rails/webpacker",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.2.0",
|
4
4
|
"description": "Use webpack to manage app-like JavaScript modules in Rails",
|
5
5
|
"main": "package/index.js",
|
6
6
|
"files": [
|
@@ -20,7 +20,6 @@
|
|
20
20
|
"babel-polyfill": "^6.26.0",
|
21
21
|
"babel-preset-env": "^1.6.1",
|
22
22
|
"case-sensitive-paths-webpack-plugin": "^2.1.1",
|
23
|
-
"coffee-loader": "^0.9.0",
|
24
23
|
"compression-webpack-plugin": "^1.0.1",
|
25
24
|
"css-loader": "^0.28.7",
|
26
25
|
"extract-text-webpack-plugin": "^3.0.2",
|
@@ -30,17 +29,15 @@
|
|
30
29
|
"node-sass": "^4.7.2",
|
31
30
|
"path-complete-extname": "^0.1.0",
|
32
31
|
"postcss-cssnext": "^3.0.2",
|
32
|
+
"postcss-import": "^11.0.0",
|
33
33
|
"postcss-loader": "^2.0.9",
|
34
|
-
"postcss-smart-import": "^0.7.5",
|
35
|
-
"rails-erb-loader": "^5.2.1",
|
36
34
|
"sass-loader": "^6.0.6",
|
37
35
|
"style-loader": "^0.19.0",
|
38
|
-
"
|
39
|
-
"webpack": "^3.8.1",
|
36
|
+
"webpack": "^3.10.0",
|
40
37
|
"webpack-manifest-plugin": "^1.3.2"
|
41
38
|
},
|
42
39
|
"devDependencies": {
|
43
|
-
"eslint": "^4.
|
40
|
+
"eslint": "^4.13.0",
|
44
41
|
"eslint-config-airbnb": "^16.1.0",
|
45
42
|
"eslint-plugin-import": "^2.8.0",
|
46
43
|
"eslint-plugin-jsx-a11y": "^6.0.2",
|
@@ -53,9 +50,6 @@
|
|
53
50
|
"<rootDir>/package"
|
54
51
|
]
|
55
52
|
},
|
56
|
-
"peerDependencies": {
|
57
|
-
"coffeescript": ">= 1.12.7 || >= 2.x"
|
58
|
-
},
|
59
53
|
"scripts": {
|
60
54
|
"test": "jest",
|
61
55
|
"lint": "eslint {package,lib}/"
|
@@ -0,0 +1,74 @@
|
|
1
|
+
/* global test expect, describe, afterAll, beforeEach */
|
2
|
+
|
3
|
+
// environment.js expects to find config/webpacker.yml and resolved modules from
|
4
|
+
// the root of a Rails project
|
5
|
+
|
6
|
+
const chdirApp = () => process.chdir('test/test_app')
|
7
|
+
const chdirCwd = () => process.chdir(process.cwd())
|
8
|
+
chdirApp()
|
9
|
+
|
10
|
+
const { resolve } = require('path')
|
11
|
+
const rules = require('../rules')
|
12
|
+
const { ConfigList } = require('../config_types')
|
13
|
+
const Environment = require('../environment')
|
14
|
+
|
15
|
+
describe('Environment', () => {
|
16
|
+
afterAll(chdirCwd)
|
17
|
+
|
18
|
+
let environment
|
19
|
+
|
20
|
+
describe('toWebpackConfig', () => {
|
21
|
+
beforeEach(() => {
|
22
|
+
environment = new Environment()
|
23
|
+
})
|
24
|
+
|
25
|
+
test('should return entry', () => {
|
26
|
+
const config = environment.toWebpackConfig()
|
27
|
+
expect(config.entry.application).toEqual(resolve('app', 'javascript', 'packs', 'application.js'))
|
28
|
+
})
|
29
|
+
|
30
|
+
test('should return output', () => {
|
31
|
+
const config = environment.toWebpackConfig()
|
32
|
+
expect(config.output.filename).toEqual('[name]-[chunkhash].js')
|
33
|
+
expect(config.output.chunkFilename).toEqual('[name]-[chunkhash].chunk.js')
|
34
|
+
expect(config.output.path).toEqual(resolve('public', 'packs-test'))
|
35
|
+
expect(config.output.publicPath).toEqual('/packs-test/')
|
36
|
+
})
|
37
|
+
|
38
|
+
test('should return default loader rules for each file in config/loaders', () => {
|
39
|
+
const config = environment.toWebpackConfig()
|
40
|
+
const defaultRules = Object.keys(rules)
|
41
|
+
const configRules = config.module.rules
|
42
|
+
|
43
|
+
expect(defaultRules.length).toBeGreaterThan(1)
|
44
|
+
expect(configRules.length).toEqual(defaultRules.length)
|
45
|
+
})
|
46
|
+
|
47
|
+
test('should return default plugins', () => {
|
48
|
+
const config = environment.toWebpackConfig()
|
49
|
+
expect(config.plugins.length).toEqual(4)
|
50
|
+
})
|
51
|
+
|
52
|
+
test('should return default resolveLoader', () => {
|
53
|
+
const config = environment.toWebpackConfig()
|
54
|
+
expect(config.resolveLoader.modules).toEqual(['node_modules'])
|
55
|
+
})
|
56
|
+
|
57
|
+
test('should return default resolve.modules with additions', () => {
|
58
|
+
const config = environment.toWebpackConfig()
|
59
|
+
expect(config.resolve.modules).toEqual([
|
60
|
+
resolve('app', 'javascript'),
|
61
|
+
resolve('app/assets'),
|
62
|
+
resolve('/etc/yarn'),
|
63
|
+
'node_modules'
|
64
|
+
])
|
65
|
+
})
|
66
|
+
|
67
|
+
test('returns plugins property as Array', () => {
|
68
|
+
const config = environment.toWebpackConfig()
|
69
|
+
|
70
|
+
expect(config.plugins).toBeInstanceOf(Array)
|
71
|
+
expect(config.plugins).not.toBeInstanceOf(ConfigList)
|
72
|
+
})
|
73
|
+
})
|
74
|
+
})
|
data/package/config.js
CHANGED
data/package/environment.js
CHANGED
@@ -15,7 +15,6 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
|
|
15
15
|
const { ConfigList, ConfigObject } = require('./config_types')
|
16
16
|
const rules = require('./rules')
|
17
17
|
const config = require('./config')
|
18
|
-
const assetHost = require('./asset_host')
|
19
18
|
|
20
19
|
const getLoaderList = () => {
|
21
20
|
const result = new ConfigList()
|
@@ -28,7 +27,7 @@ const getPluginList = () => {
|
|
28
27
|
result.append('Environment', new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env))))
|
29
28
|
result.append('CaseSensitivePaths', new CaseSensitivePathsPlugin())
|
30
29
|
result.append('ExtractText', new ExtractTextPlugin('[name]-[contenthash].css'))
|
31
|
-
result.append('Manifest', new ManifestPlugin({ publicPath:
|
30
|
+
result.append('Manifest', new ManifestPlugin({ publicPath: config.publicPath, writeToFileEmit: true }))
|
32
31
|
return result
|
33
32
|
}
|
34
33
|
|
@@ -56,10 +55,10 @@ const getEntryObject = () => {
|
|
56
55
|
const getModulePaths = () => {
|
57
56
|
const result = new ConfigList()
|
58
57
|
result.append('source', resolve(config.source_path))
|
59
|
-
result.append('node_modules', 'node_modules')
|
60
58
|
if (config.resolved_paths) {
|
61
|
-
config.resolved_paths.forEach(path => result.append(
|
59
|
+
config.resolved_paths.forEach(path => result.append(path, resolve(path)))
|
62
60
|
}
|
61
|
+
result.append('node_modules', 'node_modules')
|
63
62
|
return result
|
64
63
|
}
|
65
64
|
|
@@ -68,8 +67,8 @@ const getBaseConfig = () =>
|
|
68
67
|
output: {
|
69
68
|
filename: '[name]-[chunkhash].js',
|
70
69
|
chunkFilename: '[name]-[chunkhash].chunk.js',
|
71
|
-
path:
|
72
|
-
publicPath:
|
70
|
+
path: config.outputPath,
|
71
|
+
publicPath: config.publicPath
|
73
72
|
},
|
74
73
|
|
75
74
|
resolve: {
|
@@ -104,9 +103,7 @@ module.exports = class Environment {
|
|
104
103
|
|
105
104
|
module: {
|
106
105
|
strictExportPresence: true,
|
107
|
-
rules:
|
108
|
-
{ oneOf: this.loaders.values() }
|
109
|
-
]
|
106
|
+
rules: this.loaders.values()
|
110
107
|
},
|
111
108
|
|
112
109
|
plugins: this.plugins.values(),
|
@@ -1,7 +1,6 @@
|
|
1
1
|
const webpack = require('webpack')
|
2
2
|
const Environment = require('../environment')
|
3
|
-
const { dev_server: devServer } = require('../config')
|
4
|
-
const assetHost = require('../asset_host')
|
3
|
+
const { dev_server: devServer, outputPath: contentBase, publicPath } = require('../config')
|
5
4
|
|
6
5
|
module.exports = class extends Environment {
|
7
6
|
constructor() {
|
@@ -27,11 +26,11 @@ module.exports = class extends Environment {
|
|
27
26
|
port: devServer.port,
|
28
27
|
https: devServer.https,
|
29
28
|
hot: devServer.hmr,
|
30
|
-
contentBase
|
29
|
+
contentBase,
|
31
30
|
inline: devServer.inline,
|
32
31
|
useLocalIp: devServer.use_local_ip,
|
33
32
|
public: devServer.public,
|
34
|
-
publicPath
|
33
|
+
publicPath,
|
35
34
|
historyApiFallback: {
|
36
35
|
disableDotRule: true
|
37
36
|
},
|
data/package/index.js
CHANGED
@@ -5,7 +5,6 @@ const { resolve } = require('path')
|
|
5
5
|
const { existsSync } = require('fs')
|
6
6
|
const Environment = require('./environment')
|
7
7
|
const config = require('./config')
|
8
|
-
const assetHost = require('./asset_host')
|
9
8
|
const loaders = require('./rules')
|
10
9
|
|
11
10
|
const createEnvironment = () => {
|
@@ -17,5 +16,5 @@ const createEnvironment = () => {
|
|
17
16
|
const environment = createEnvironment()
|
18
17
|
|
19
18
|
module.exports = {
|
20
|
-
environment, config,
|
19
|
+
environment, config, loaders, Environment
|
21
20
|
}
|
data/package/rules/file.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
const { join } = require('path')
|
2
2
|
const { source_path } = require('../config')
|
3
|
-
const assetHost = require('../asset_host')
|
4
3
|
|
5
4
|
module.exports = {
|
6
5
|
exclude: /\.(js|jsx|coffee|ts|tsx|vue|elm|scss|sass|css|html|json)?(\.erb)?$/,
|
@@ -8,8 +7,7 @@ module.exports = {
|
|
8
7
|
loader: 'file-loader',
|
9
8
|
options: {
|
10
9
|
name: '[path][name]-[hash].[ext]',
|
11
|
-
context: join(source_path)
|
12
|
-
publicPath: assetHost.publicPathWithHost
|
10
|
+
context: join(source_path)
|
13
11
|
}
|
14
12
|
}]
|
15
13
|
}
|
data/package/rules/index.js
CHANGED
@@ -1,23 +1,11 @@
|
|
1
1
|
const babel = require('./babel')
|
2
|
-
const coffee = require('./coffee')
|
3
|
-
const elm = require('./elm')
|
4
|
-
const erb = require('./erb')
|
5
2
|
const file = require('./file')
|
6
|
-
const url = require('./url')
|
7
3
|
const css = require('./css')
|
8
4
|
const sass = require('./sass')
|
9
|
-
const typescript = require('./typescript')
|
10
|
-
const vue = require('./vue')
|
11
5
|
|
12
6
|
module.exports = {
|
13
|
-
url,
|
14
7
|
babel,
|
15
|
-
coffee,
|
16
|
-
elm,
|
17
|
-
erb,
|
18
8
|
css,
|
19
9
|
sass,
|
20
|
-
typescript,
|
21
|
-
vue,
|
22
10
|
file
|
23
11
|
}
|
data/test/compiler_test.rb
CHANGED
@@ -13,6 +13,17 @@ class CompilerTest < Minitest::Test
|
|
13
13
|
assert Webpacker.compiler.send(:webpack_env)["FOO"] == "BAR"
|
14
14
|
end
|
15
15
|
|
16
|
+
def test_default_watched_paths
|
17
|
+
assert_equal Webpacker.compiler.send(:default_watched_paths), [
|
18
|
+
"app/assets/**/*",
|
19
|
+
"/etc/yarn/**/*",
|
20
|
+
"test/test_app/app/javascript/**/*",
|
21
|
+
"yarn.lock",
|
22
|
+
"package.json",
|
23
|
+
"config/webpack/**/*"
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
16
27
|
def test_freshness
|
17
28
|
assert Webpacker.compiler.stale?
|
18
29
|
assert !Webpacker.compiler.fresh?
|
data/test/configuration_test.rb
CHANGED
@@ -26,6 +26,14 @@ class ConfigurationTest < Webpacker::Test
|
|
26
26
|
assert_equal Webpacker.config.cache_path.to_s, cache_path
|
27
27
|
end
|
28
28
|
|
29
|
+
def test_resolved_paths
|
30
|
+
assert_equal Webpacker.config.resolved_paths, ["app/assets", "/etc/yarn"]
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_resolved_paths_globbed
|
34
|
+
assert_equal Webpacker.config.resolved_paths_globbed, ["app/assets/**/*", "/etc/yarn/**/*"]
|
35
|
+
end
|
36
|
+
|
29
37
|
def test_extensions
|
30
38
|
webpacker_yml = YAML.load_file("lib/install/config/webpacker.yml")
|
31
39
|
assert_equal Webpacker.config.extensions, webpacker_yml["default"]["extensions"]
|
data/test/helper_test.rb
CHANGED
@@ -8,6 +8,9 @@ class HelperTest < ActionView::TestCase
|
|
8
8
|
def setup
|
9
9
|
@request = Class.new do
|
10
10
|
def send_early_hints(links) end
|
11
|
+
def base_url
|
12
|
+
"https://example.com"
|
13
|
+
end
|
11
14
|
end.new
|
12
15
|
end
|
13
16
|
|
@@ -16,6 +19,11 @@ class HelperTest < ActionView::TestCase
|
|
16
19
|
assert_equal "/packs/bootstrap-c38deda30895059837cf.css", asset_pack_path("bootstrap.css")
|
17
20
|
end
|
18
21
|
|
22
|
+
def test_asset_pack_url
|
23
|
+
assert_equal "https://example.com/packs/bootstrap-300631c4f0e0f9c865bc.js", asset_pack_url("bootstrap.js")
|
24
|
+
assert_equal "https://example.com/packs/bootstrap-c38deda30895059837cf.css", asset_pack_url("bootstrap.css")
|
25
|
+
end
|
26
|
+
|
19
27
|
def test_javascript_pack_tag
|
20
28
|
assert_equal \
|
21
29
|
%(<script src="/packs/bootstrap-300631c4f0e0f9c865bc.js"></script>),
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/* eslint no-console:0 */
|
2
|
+
// This file is automatically compiled by Webpack, along with any other files
|
3
|
+
// present in this directory. You're encouraged to place your actual application logic in
|
4
|
+
// a relevant structure within app/javascript and only use these pack files to reference
|
5
|
+
// that code so it'll be compiled.
|
6
|
+
//
|
7
|
+
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
|
8
|
+
// layout file, like app/views/layouts/application.html.erb
|
9
|
+
|
10
|
+
console.log('Hello World from Webpacker')
|