webpacker 2.0 → 3.0.0
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/.gitignore +2 -0
- data/.rubocop.yml +21 -21
- data/CHANGELOG.md +107 -4
- data/Gemfile +3 -1
- data/Gemfile.lock +15 -8
- data/README.md +137 -937
- data/docs/assets.md +106 -0
- data/docs/css.md +82 -0
- data/docs/deployment.md +39 -0
- data/docs/env.md +62 -0
- data/docs/es6.md +53 -0
- data/docs/folder-structure.md +66 -0
- data/docs/misc.md +23 -0
- data/docs/props.md +105 -0
- data/docs/testing.md +45 -0
- data/docs/troubleshooting.md +65 -0
- data/docs/typescript.md +115 -0
- data/docs/webpack-dev-server.md +32 -0
- data/docs/webpack.md +108 -0
- data/docs/yarn.md +12 -0
- data/lib/install/angular.rb +4 -7
- data/lib/install/bin/webpack-dev-server.tt +35 -11
- data/lib/install/bin/webpack.tt +3 -4
- data/lib/install/config/.babelrc +1 -0
- data/lib/install/config/.postcssrc.yml +1 -2
- data/lib/install/config/webpack/development.js +2 -31
- data/lib/install/config/webpack/environment.js +3 -0
- data/lib/install/config/webpack/production.js +2 -34
- data/lib/install/config/webpack/test.js +2 -5
- data/lib/install/config/webpacker.yml +20 -2
- data/lib/install/elm.rb +6 -11
- data/lib/install/examples/vue/hello_vue.js +31 -2
- data/lib/install/react.rb +2 -5
- data/lib/install/template.rb +3 -8
- data/lib/install/vue.rb +4 -7
- data/lib/tasks/webpacker.rake +1 -1
- data/lib/tasks/webpacker/{check_webpack_binstubs.rake → check_binstubs.rake} +3 -2
- data/lib/tasks/webpacker/check_node.rake +8 -6
- data/lib/tasks/webpacker/check_yarn.rake +2 -2
- data/lib/tasks/webpacker/clobber.rake +2 -3
- data/lib/tasks/webpacker/compile.rake +16 -18
- data/lib/tasks/webpacker/verify_install.rake +5 -5
- data/lib/tasks/webpacker/yarn_install.rake +1 -1
- data/lib/webpacker.rb +15 -11
- data/lib/webpacker/commands.rb +22 -0
- data/lib/webpacker/compiler.rb +66 -10
- data/lib/webpacker/configuration.rb +54 -38
- data/lib/webpacker/dev_server.rb +47 -0
- data/lib/webpacker/dev_server_proxy.rb +24 -0
- data/lib/webpacker/helper.rb +23 -5
- data/lib/webpacker/instance.rb +44 -0
- data/lib/webpacker/manifest.rb +58 -34
- data/lib/webpacker/railtie.rb +22 -3
- data/lib/webpacker/version.rb +2 -1
- data/package.json +37 -7
- data/package/asset_host.js +21 -0
- data/package/config.js +8 -0
- data/package/environment.js +95 -0
- data/package/environments/development.js +47 -0
- data/package/environments/production.js +34 -0
- data/package/environments/test.js +3 -0
- data/package/index.js +16 -0
- data/package/loaders/babel.js +11 -0
- data/{lib/install/config/loaders/core → package/loaders}/coffee.js +0 -0
- data/{lib/install/config/loaders/installers → package/loaders}/elm.js +4 -5
- data/{lib/install/config/loaders/core → package/loaders}/erb.js +0 -0
- data/package/loaders/file.js +15 -0
- data/package/loaders/style.js +31 -0
- data/{lib/install/config/loaders/installers/angular.js → package/loaders/typescript.js} +1 -1
- data/package/loaders/vue.js +12 -0
- data/test/compiler_test.rb +20 -0
- data/test/configuration_test.rb +43 -19
- data/test/dev_server_test.rb +24 -0
- data/test/helper_test.rb +21 -5
- data/test/manifest_test.rb +25 -19
- data/test/test_app/public/packs/manifest.json +3 -1
- data/test/webpacker_test_helper.rb +40 -0
- data/webpacker.gemspec +1 -1
- data/yarn.lock +4701 -578
- metadata +52 -29
- data/lib/install/config/loaders/core/assets.js +0 -12
- data/lib/install/config/loaders/core/babel.js +0 -5
- data/lib/install/config/loaders/core/sass.js +0 -15
- data/lib/install/config/loaders/installers/react.js +0 -5
- data/lib/install/config/loaders/installers/vue.js +0 -13
- data/lib/install/config/webpack/configuration.js +0 -35
- data/lib/install/config/webpack/shared.js +0 -58
- data/lib/webpacker/env.rb +0 -23
- data/lib/webpacker/file_loader.rb +0 -24
- data/test/env_test.rb +0 -14
- data/test/webpacker_test.rb +0 -15
data/lib/webpacker/manifest.rb
CHANGED
@@ -1,51 +1,75 @@
|
|
1
|
-
# Singleton registry for accessing the packs path using generated manifest.
|
1
|
+
# Singleton registry for accessing the packs path using a generated manifest.
|
2
2
|
# This allows javascript_pack_tag, stylesheet_pack_tag, asset_pack_path to take a reference to,
|
3
3
|
# say, "calendar.js" or "calendar.css" and turn it into "/packs/calendar.js" or
|
4
|
-
# "/packs/calendar.css" in development.
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# "/packs/calendar.css" in development.
|
5
|
+
#
|
6
|
+
# In production mode, it returns compiles files, like
|
7
|
+
# "/packs/calendar-1016838bab065ae1e314.js" and "/packs/calendar-1016838bab065ae1e314.css",
|
8
|
+
# for long-term caching.
|
9
|
+
#
|
10
|
+
# When the configuration is set to on-demand compilation, with the `compile: true` option in
|
11
|
+
# the webpacker.yml file, any lookups will be preceeded by a compilation if one is needed.
|
12
|
+
class Webpacker::Manifest
|
13
|
+
class MissingEntryError < StandardError; end
|
7
14
|
|
8
|
-
|
15
|
+
delegate :config, :compiler, :dev_server, to: :@webpacker
|
9
16
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
Webpacker::Configuration.manifest_path
|
14
|
-
end
|
17
|
+
def initialize(webpacker)
|
18
|
+
@webpacker = webpacker
|
19
|
+
end
|
15
20
|
|
16
|
-
|
17
|
-
|
21
|
+
def refresh
|
22
|
+
@data = load
|
23
|
+
end
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
def lookup(name)
|
26
|
+
compile if compiling?
|
27
|
+
find name
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def compiling?
|
32
|
+
config.compile? && !dev_server.running?
|
24
33
|
end
|
25
34
|
|
26
|
-
def
|
27
|
-
|
35
|
+
def compile
|
36
|
+
Webpacker.logger.tagged("Webpacker") { compiler.compile }
|
28
37
|
end
|
29
38
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
39
|
+
def find(name)
|
40
|
+
data[name.to_s] || handle_missing_entry(name)
|
41
|
+
end
|
34
42
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
43
|
+
def handle_missing_entry(name)
|
44
|
+
raise Webpacker::Manifest::MissingEntryError, missing_file_from_manifest_error(name)
|
45
|
+
end
|
39
46
|
|
40
|
-
|
41
|
-
|
42
|
-
|
47
|
+
def missing_file_from_manifest_error(bundle_name)
|
48
|
+
msg = <<-MSG
|
49
|
+
Webpacker can't find #{bundle_name} in #{config.public_manifest_path}. Possible causes:
|
50
|
+
1. You want to set wepbacker.yml value of compile to true for your environment
|
51
|
+
unless you are using the `webpack -w` or the webpack-dev-server.
|
52
|
+
2. Webpack has not yet re-run to reflect updates.
|
53
|
+
3. You have misconfigured Webpacker's config/webpacker.yml file.
|
54
|
+
4. Your Webpack configuration is not creating a manifest.
|
55
|
+
Your manifest contains:
|
56
|
+
#{JSON.pretty_generate(@data)}
|
57
|
+
MSG
|
58
|
+
end
|
59
|
+
|
60
|
+
def data
|
61
|
+
if config.cache_manifest?
|
62
|
+
@data ||= load
|
63
|
+
else
|
64
|
+
refresh
|
43
65
|
end
|
44
|
-
|
66
|
+
end
|
45
67
|
|
46
|
-
private
|
47
68
|
def load
|
48
|
-
|
49
|
-
|
69
|
+
if config.public_manifest_path.exist?
|
70
|
+
JSON.parse config.public_manifest_path.read
|
71
|
+
else
|
72
|
+
{}
|
73
|
+
end
|
50
74
|
end
|
51
75
|
end
|
data/lib/webpacker/railtie.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
require "rails/railtie"
|
2
2
|
|
3
3
|
require "webpacker/helper"
|
4
|
+
require "webpacker/dev_server_proxy"
|
4
5
|
|
5
6
|
class Webpacker::Engine < ::Rails::Engine
|
6
|
-
initializer
|
7
|
+
initializer "webpacker.proxy" do |app|
|
8
|
+
if Rails.env.development?
|
9
|
+
app.middleware.insert_before 0,
|
10
|
+
Rails::VERSION::MAJOR >= 5 ?
|
11
|
+
Webpacker::DevServerProxy : "Webpacker::DevServerProxy", ssl_verify_none: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
initializer "webpacker.helper" do |app|
|
7
16
|
ActiveSupport.on_load :action_controller do
|
8
17
|
ActionController::Base.helper Webpacker::Helper
|
9
18
|
end
|
@@ -11,8 +20,18 @@ class Webpacker::Engine < ::Rails::Engine
|
|
11
20
|
ActiveSupport.on_load :action_view do
|
12
21
|
include Webpacker::Helper
|
13
22
|
end
|
23
|
+
end
|
24
|
+
|
25
|
+
initializer "webpacker.logger" do
|
26
|
+
config.after_initialize do |app|
|
27
|
+
Webpacker.logger = ::Rails.logger
|
28
|
+
end
|
29
|
+
end
|
14
30
|
|
15
|
-
|
16
|
-
|
31
|
+
initializer "webpacker.bootstrap" do
|
32
|
+
if defined?(Rails::Server) || defined?(Rails::Console)
|
33
|
+
Webpacker.bootstrap
|
34
|
+
Spring.after_fork { Webpacker.bootstrap } if defined?(Spring)
|
35
|
+
end
|
17
36
|
end
|
18
37
|
end
|
data/lib/webpacker/version.rb
CHANGED
data/package.json
CHANGED
@@ -1,12 +1,42 @@
|
|
1
1
|
{
|
2
|
-
"name": "webpacker",
|
3
|
-
"version": "
|
4
|
-
"description": "
|
5
|
-
"main": "index.js",
|
2
|
+
"name": "@rails/webpacker",
|
3
|
+
"version": "3.0.0",
|
4
|
+
"description": "Use Webpack to manage app-like JavaScript modules in Rails",
|
5
|
+
"main": "package/index.js",
|
6
|
+
"files": [
|
7
|
+
"package"
|
8
|
+
],
|
6
9
|
"engines": {
|
7
|
-
"node": ">= 6.
|
10
|
+
"node": ">= 6.0.0"
|
11
|
+
},
|
12
|
+
"dependencies": {
|
13
|
+
"babel-core": "^6.26.0",
|
14
|
+
"babel-loader": "^7.1.2",
|
15
|
+
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
16
|
+
"babel-plugin-transform-class-properties": "^6.24.1",
|
17
|
+
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
18
|
+
"babel-polyfill": "^6.26.0",
|
19
|
+
"babel-preset-env": "^1.6.0",
|
20
|
+
"coffee-loader": "^0.8.0",
|
21
|
+
"coffee-script": "^1.12.7",
|
22
|
+
"compression-webpack-plugin": "^1.0.0",
|
23
|
+
"css-loader": "^0.28.5",
|
24
|
+
"extract-text-webpack-plugin": "^3.0.0",
|
25
|
+
"file-loader": "^0.11.2",
|
26
|
+
"glob": "^7.1.2",
|
27
|
+
"js-yaml": "^3.9.1",
|
28
|
+
"node-sass": "^4.5.3",
|
29
|
+
"path-complete-extname": "^0.1.0",
|
30
|
+
"postcss-cssnext": "^3.0.2",
|
31
|
+
"postcss-loader": "^2.0.6",
|
32
|
+
"postcss-smart-import": "^0.7.5",
|
33
|
+
"rails-erb-loader": "^5.2.1",
|
34
|
+
"resolve-url-loader": "^2.1.0",
|
35
|
+
"sass-loader": "^6.0.6",
|
36
|
+
"style-loader": "^0.18.2",
|
37
|
+
"webpack": "^3.5.5",
|
38
|
+
"webpack-manifest-plugin": "^1.3.1"
|
8
39
|
},
|
9
|
-
"dependencies": {},
|
10
40
|
"devDependencies": {
|
11
41
|
"eslint": "^3.16.1",
|
12
42
|
"eslint-config-airbnb": "^14.1.0",
|
@@ -16,7 +46,7 @@
|
|
16
46
|
},
|
17
47
|
"scripts": {
|
18
48
|
"test": "echo \"Error: no test specified\" && exit 1",
|
19
|
-
"lint": "
|
49
|
+
"lint": "eslint {package,lib}/"
|
20
50
|
},
|
21
51
|
"repository": {
|
22
52
|
"type": "git",
|
@@ -0,0 +1,21 @@
|
|
1
|
+
const config = require('./config')
|
2
|
+
const { resolve } = require('path')
|
3
|
+
|
4
|
+
function removeOuterSlashes(string) {
|
5
|
+
return string.replace(/^\/*/, '').replace(/\/*$/, '')
|
6
|
+
}
|
7
|
+
|
8
|
+
function formatPublicPath(host = '', path = '') {
|
9
|
+
let formattedHost = removeOuterSlashes(host)
|
10
|
+
if (formattedHost && !/^http/i.test(formattedHost)) {
|
11
|
+
formattedHost = `//${formattedHost}`
|
12
|
+
}
|
13
|
+
const formattedPath = removeOuterSlashes(path)
|
14
|
+
return `${formattedHost}/${formattedPath}/`
|
15
|
+
}
|
16
|
+
|
17
|
+
module.exports = {
|
18
|
+
path: resolve('public', config.public_output_path),
|
19
|
+
publicPath: `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1'),
|
20
|
+
publicPathWithHost: formatPublicPath(process.env.ASSET_HOST, config.public_output_path)
|
21
|
+
}
|
data/package/config.js
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
const { resolve } = require('path')
|
2
|
+
const { safeLoad } = require('js-yaml')
|
3
|
+
const { readFileSync } = require('fs')
|
4
|
+
|
5
|
+
const filePath = resolve('config', 'webpacker.yml')
|
6
|
+
const config = safeLoad(readFileSync(filePath), 'utf8')
|
7
|
+
|
8
|
+
module.exports = config[process.env.NODE_ENV]
|
@@ -0,0 +1,95 @@
|
|
1
|
+
/* eslint global-require: 0 */
|
2
|
+
/* eslint import/no-dynamic-require: 0 */
|
3
|
+
|
4
|
+
const config = require('./config')
|
5
|
+
const assetHost = require('./asset_host')
|
6
|
+
|
7
|
+
const { basename, dirname, join, relative, resolve } = require('path')
|
8
|
+
const { sync } = require('glob')
|
9
|
+
const extname = require('path-complete-extname')
|
10
|
+
|
11
|
+
const webpack = require('webpack')
|
12
|
+
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
13
|
+
const ManifestPlugin = require('webpack-manifest-plugin')
|
14
|
+
|
15
|
+
function getLoaderMap() {
|
16
|
+
const result = new Map()
|
17
|
+
const paths = sync(resolve(__dirname, 'loaders', '*.js'))
|
18
|
+
paths.forEach((path) => {
|
19
|
+
const name = basename(path, extname(path))
|
20
|
+
result.set(name, require(path))
|
21
|
+
})
|
22
|
+
return result
|
23
|
+
}
|
24
|
+
|
25
|
+
function getPluginMap() {
|
26
|
+
const result = new Map()
|
27
|
+
result.set('Environment', new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env))))
|
28
|
+
result.set('ExtractText', new ExtractTextPlugin('[name]-[contenthash].css'))
|
29
|
+
result.set('Manifest', new ManifestPlugin({ publicPath: assetHost.publicPath, writeToFileEmit: true }))
|
30
|
+
return result
|
31
|
+
}
|
32
|
+
|
33
|
+
function getExtensionsGlob() {
|
34
|
+
const { extensions } = config
|
35
|
+
if (!extensions.length) {
|
36
|
+
throw new Error('You must configure at least one extension to compile in webpacker.yml')
|
37
|
+
}
|
38
|
+
return extensions.length === 1 ? `**/${extensions[0]}` : `**/*{${extensions.join(',')}}`
|
39
|
+
}
|
40
|
+
|
41
|
+
function getEntryObject() {
|
42
|
+
const result = {}
|
43
|
+
const glob = getExtensionsGlob()
|
44
|
+
const rootPath = join(config.source_path, config.source_entry_path)
|
45
|
+
const paths = sync(join(rootPath, glob))
|
46
|
+
paths.forEach((path) => {
|
47
|
+
const namespace = relative(join(rootPath), dirname(path))
|
48
|
+
const name = join(namespace, basename(path, extname(path)))
|
49
|
+
result[name] = resolve(path)
|
50
|
+
})
|
51
|
+
return result
|
52
|
+
}
|
53
|
+
|
54
|
+
function getModulePaths() {
|
55
|
+
let result = [resolve(config.source_path), 'node_modules']
|
56
|
+
if (config.resolved_paths) {
|
57
|
+
result = result.concat(config.resolved_paths)
|
58
|
+
}
|
59
|
+
return result
|
60
|
+
}
|
61
|
+
|
62
|
+
module.exports = class Environment {
|
63
|
+
constructor() {
|
64
|
+
this.loaders = getLoaderMap()
|
65
|
+
this.plugins = getPluginMap()
|
66
|
+
}
|
67
|
+
|
68
|
+
toWebpackConfig() {
|
69
|
+
return {
|
70
|
+
entry: getEntryObject(),
|
71
|
+
|
72
|
+
output: {
|
73
|
+
filename: '[name]-[chunkhash].js',
|
74
|
+
chunkFilename: '[name]-[chunkhash].chunk.js',
|
75
|
+
path: assetHost.path,
|
76
|
+
publicPath: assetHost.publicPath
|
77
|
+
},
|
78
|
+
|
79
|
+
module: {
|
80
|
+
rules: Array.from(this.loaders.values())
|
81
|
+
},
|
82
|
+
|
83
|
+
plugins: Array.from(this.plugins.values()),
|
84
|
+
|
85
|
+
resolve: {
|
86
|
+
extensions: config.extensions,
|
87
|
+
modules: getModulePaths()
|
88
|
+
},
|
89
|
+
|
90
|
+
resolveLoader: {
|
91
|
+
modules: ['node_modules']
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
const Environment = require('../environment')
|
2
|
+
const { dev_server } = require('../config')
|
3
|
+
const assetHost = require('../asset_host')
|
4
|
+
const webpack = require('webpack')
|
5
|
+
|
6
|
+
module.exports = class extends Environment {
|
7
|
+
constructor() {
|
8
|
+
super()
|
9
|
+
|
10
|
+
if (dev_server.hmr) {
|
11
|
+
this.plugins.set('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
|
12
|
+
this.plugins.set('NamedModules', new webpack.NamedModulesPlugin())
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
toWebpackConfig() {
|
17
|
+
const result = super.toWebpackConfig()
|
18
|
+
if (dev_server.hmr) {
|
19
|
+
result.output.filename = '[name]-[hash].js'
|
20
|
+
}
|
21
|
+
result.output.pathinfo = true
|
22
|
+
result.devtool = 'cheap-eval-source-map'
|
23
|
+
result.devServer = {
|
24
|
+
host: dev_server.host,
|
25
|
+
port: dev_server.port,
|
26
|
+
https: dev_server.https,
|
27
|
+
hot: dev_server.hmr,
|
28
|
+
contentBase: assetHost.path,
|
29
|
+
publicPath: assetHost.publicPath,
|
30
|
+
clientLogLevel: 'none',
|
31
|
+
compress: true,
|
32
|
+
historyApiFallback: true,
|
33
|
+
headers: {
|
34
|
+
'Access-Control-Allow-Origin': '*'
|
35
|
+
},
|
36
|
+
overlay: true,
|
37
|
+
watchContentBase: true,
|
38
|
+
watchOptions: {
|
39
|
+
ignored: /node_modules/
|
40
|
+
},
|
41
|
+
stats: {
|
42
|
+
errorDetails: true
|
43
|
+
}
|
44
|
+
}
|
45
|
+
return result
|
46
|
+
}
|
47
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
const Environment = require('../environment')
|
2
|
+
const webpack = require('webpack')
|
3
|
+
const CompressionPlugin = require('compression-webpack-plugin')
|
4
|
+
|
5
|
+
module.exports = class extends Environment {
|
6
|
+
constructor() {
|
7
|
+
super()
|
8
|
+
|
9
|
+
this.plugins.set('ModuleConcatenation', new webpack.optimize.ModuleConcatenationPlugin())
|
10
|
+
|
11
|
+
this.plugins.set('UglifyJs', new webpack.optimize.UglifyJsPlugin({
|
12
|
+
sourceMap: true,
|
13
|
+
compress: {
|
14
|
+
warnings: false
|
15
|
+
},
|
16
|
+
output: {
|
17
|
+
comments: false
|
18
|
+
}
|
19
|
+
}))
|
20
|
+
|
21
|
+
this.plugins.set('Compression', new CompressionPlugin({
|
22
|
+
asset: '[path].gz[query]',
|
23
|
+
algorithm: 'gzip',
|
24
|
+
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
|
25
|
+
}))
|
26
|
+
}
|
27
|
+
|
28
|
+
toWebpackConfig() {
|
29
|
+
const result = super.toWebpackConfig()
|
30
|
+
result.devtool = 'source-map'
|
31
|
+
result.stats = 'normal'
|
32
|
+
return result
|
33
|
+
}
|
34
|
+
}
|
data/package/index.js
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
/* eslint global-require: 0 */
|
2
|
+
/* eslint import/no-dynamic-require: 0 */
|
3
|
+
|
4
|
+
const Environment = require('./environment')
|
5
|
+
const { resolve } = require('path')
|
6
|
+
const { existsSync } = require('fs')
|
7
|
+
|
8
|
+
function createEnvironment() {
|
9
|
+
const path = resolve(__dirname, 'environments', `${process.env.NODE_ENV}.js`)
|
10
|
+
const constructor = existsSync(path) ? require(path) : Environment
|
11
|
+
return new constructor()
|
12
|
+
}
|
13
|
+
|
14
|
+
const environment = createEnvironment()
|
15
|
+
|
16
|
+
module.exports = { environment, Environment }
|