webpacker 3.0.2 → 3.1.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/.eslintignore +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +110 -0
- data/Gemfile.lock +69 -67
- data/MIT-LICENSE +1 -1
- data/README.md +86 -30
- data/docs/assets.md +4 -4
- data/docs/cloud9.md +310 -0
- data/docs/css.md +32 -3
- data/docs/deployment.md +42 -4
- data/docs/docker.md +49 -0
- data/docs/env.md +5 -5
- data/docs/folder-structure.md +2 -2
- data/docs/testing.md +14 -34
- data/docs/troubleshooting.md +40 -4
- data/docs/typescript.md +2 -2
- data/docs/webpack-dev-server.md +21 -4
- data/docs/webpack.md +103 -25
- data/gemfiles/Gemfile-rails-edge +13 -0
- data/gemfiles/Gemfile-rails.4.2.x +10 -0
- data/gemfiles/Gemfile-rails.5.0.x +10 -0
- data/gemfiles/Gemfile-rails.5.1.x +10 -0
- data/lib/install/angular.rb +5 -5
- data/lib/install/config/webpacker.yml +7 -0
- data/lib/install/elm.rb +7 -7
- data/lib/install/examples/vue/hello_vue.js +30 -4
- data/lib/install/react.rb +5 -5
- data/lib/install/template.rb +19 -9
- data/lib/install/vue.rb +4 -4
- data/lib/tasks/installers.rake +2 -2
- data/lib/tasks/webpacker.rake +7 -6
- data/lib/tasks/webpacker/check_binstubs.rake +3 -3
- data/lib/tasks/webpacker/compile.rake +15 -8
- data/lib/tasks/webpacker/install.rake +4 -4
- data/lib/tasks/webpacker/verify_install.rake +1 -1
- data/lib/webpacker/compiler.rb +6 -6
- data/lib/webpacker/dev_server.rb +2 -2
- data/lib/webpacker/dev_server_proxy.rb +2 -1
- data/lib/webpacker/dev_server_runner.rb +4 -4
- data/lib/webpacker/helper.rb +3 -3
- data/lib/webpacker/manifest.rb +2 -2
- data/lib/webpacker/railtie.rb +41 -2
- data/lib/webpacker/runner.rb +1 -1
- data/lib/webpacker/version.rb +1 -1
- data/package.json +29 -21
- data/package/asset_host.js +4 -5
- data/package/config.js +7 -1
- data/package/config_types/__tests__/config_list.js +123 -0
- data/package/config_types/__tests__/config_object.js +43 -0
- data/package/config_types/config_list.js +83 -0
- data/package/config_types/config_object.js +55 -0
- data/package/config_types/index.js +7 -0
- data/package/environment.js +64 -40
- data/package/environments/development.js +31 -34
- data/package/environments/production.js +14 -11
- data/package/index.js +7 -2
- data/package/{loaders → rules}/babel.js +6 -4
- data/package/{loaders → rules}/coffee.js +3 -1
- data/package/rules/css.js +39 -0
- data/package/rules/elm.js +23 -0
- data/package/rules/erb.js +11 -0
- data/package/{loaders → rules}/file.js +1 -1
- data/package/rules/index.js +23 -0
- data/package/rules/sass.js +15 -0
- data/package/{loaders → rules}/typescript.js +3 -1
- data/package/rules/url.js +13 -0
- data/package/rules/vue.js +13 -0
- data/package/utils/__tests__/deep_assign.js +11 -0
- data/package/utils/__tests__/deep_merge.js +10 -0
- data/package/utils/__tests__/objectify.js +9 -0
- data/package/utils/deep_assign.js +22 -0
- data/package/utils/deep_merge.js +23 -0
- data/package/utils/helpers.js +32 -0
- data/package/utils/objectify.js +4 -0
- data/test/command_test.rb +1 -1
- data/test/compiler_test.rb +5 -1
- data/test/configuration_test.rb +1 -1
- data/test/dev_server_test.rb +1 -1
- data/test/helper_test.rb +15 -10
- data/test/manifest_test.rb +1 -1
- data/test/rake_tasks_test.rb +29 -0
- data/test/test_app/Rakefile +3 -0
- data/test/test_app/config/application.rb +11 -0
- data/test/test_app/config/environment.rb +4 -0
- data/test/{webpacker_test_helper.rb → test_helper.rb} +3 -14
- data/webpacker.gemspec +1 -1
- data/yarn.lock +1552 -829
- metadata +43 -16
- data/package/loaders/elm.js +0 -19
- data/package/loaders/erb.js +0 -9
- data/package/loaders/style.js +0 -31
- data/package/loaders/vue.js +0 -12
- data/test/test_app/config/secrets.yml +0 -5
@@ -0,0 +1,55 @@
|
|
1
|
+
const objectify = require('../utils/objectify')
|
2
|
+
const deepAssign = require('../utils/deep_assign')
|
3
|
+
const deepMerge = require('../utils/deep_merge')
|
4
|
+
const { isStrPath, prettyPrint } = require('../utils/helpers')
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @class
|
8
|
+
* @extends { Object }
|
9
|
+
*/
|
10
|
+
class ConfigObject extends Object {
|
11
|
+
constructor(props = {}) {
|
12
|
+
super()
|
13
|
+
this.merge(props)
|
14
|
+
}
|
15
|
+
|
16
|
+
get(key) {
|
17
|
+
return isStrPath(key) ? objectify(key, this) : this[key]
|
18
|
+
}
|
19
|
+
|
20
|
+
set(key, value) {
|
21
|
+
Object.assign(this, deepAssign(this, key, value))
|
22
|
+
return this
|
23
|
+
}
|
24
|
+
|
25
|
+
delete(key) {
|
26
|
+
let obj = this
|
27
|
+
let propKey = key
|
28
|
+
|
29
|
+
if (isStrPath(key)) {
|
30
|
+
const keys = key.split('.')
|
31
|
+
propKey = keys.pop()
|
32
|
+
const parentObjPath = keys.join('.')
|
33
|
+
obj = objectify(parentObjPath, this)
|
34
|
+
}
|
35
|
+
|
36
|
+
if (!obj) throw new Error(`Prop not found: ${key} in ${prettyPrint(obj)}`)
|
37
|
+
delete obj[propKey]
|
38
|
+
|
39
|
+
return this
|
40
|
+
}
|
41
|
+
|
42
|
+
toObject() {
|
43
|
+
const object = {}
|
44
|
+
/* eslint no-return-assign: 0 */
|
45
|
+
Object.keys(this).forEach(key => (object[key] = this[key]))
|
46
|
+
return object
|
47
|
+
}
|
48
|
+
|
49
|
+
merge(config) {
|
50
|
+
Object.assign(this, deepMerge(this, config))
|
51
|
+
return this
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
module.exports = ConfigObject
|
data/package/environment.js
CHANGED
@@ -1,36 +1,38 @@
|
|
1
1
|
/* eslint global-require: 0 */
|
2
2
|
/* eslint import/no-dynamic-require: 0 */
|
3
3
|
|
4
|
-
const {
|
4
|
+
const {
|
5
|
+
basename, dirname, join, relative, resolve
|
6
|
+
} = require('path')
|
5
7
|
const { sync } = require('glob')
|
6
8
|
const extname = require('path-complete-extname')
|
7
9
|
|
8
10
|
const webpack = require('webpack')
|
9
11
|
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
10
12
|
const ManifestPlugin = require('webpack-manifest-plugin')
|
13
|
+
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
|
11
14
|
|
15
|
+
const { ConfigList, ConfigObject } = require('./config_types')
|
16
|
+
const rules = require('./rules')
|
12
17
|
const config = require('./config')
|
13
18
|
const assetHost = require('./asset_host')
|
14
19
|
|
15
|
-
|
16
|
-
const result = new
|
17
|
-
|
18
|
-
paths.forEach((path) => {
|
19
|
-
const name = basename(path, extname(path))
|
20
|
-
result.set(name, require(path))
|
21
|
-
})
|
20
|
+
const getLoaderList = () => {
|
21
|
+
const result = new ConfigList()
|
22
|
+
Object.keys(rules).forEach(key => result.append(key, rules[key]))
|
22
23
|
return result
|
23
24
|
}
|
24
25
|
|
25
|
-
|
26
|
-
const result = new
|
27
|
-
result.
|
28
|
-
result.
|
29
|
-
result.
|
26
|
+
const getPluginList = () => {
|
27
|
+
const result = new ConfigList()
|
28
|
+
result.append('Environment', new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env))))
|
29
|
+
result.append('CaseSensitivePaths', new CaseSensitivePathsPlugin())
|
30
|
+
result.append('ExtractText', new ExtractTextPlugin('[name]-[contenthash].css'))
|
31
|
+
result.append('Manifest', new ManifestPlugin({ publicPath: assetHost.publicPath, writeToFileEmit: true }))
|
30
32
|
return result
|
31
33
|
}
|
32
34
|
|
33
|
-
|
35
|
+
const getExtensionsGlob = () => {
|
34
36
|
const { extensions } = config
|
35
37
|
if (!extensions.length) {
|
36
38
|
throw new Error('You must configure at least one extension to compile in webpacker.yml')
|
@@ -38,58 +40,80 @@ function getExtensionsGlob() {
|
|
38
40
|
return extensions.length === 1 ? `**/${extensions[0]}` : `**/*{${extensions.join(',')}}`
|
39
41
|
}
|
40
42
|
|
41
|
-
|
42
|
-
const result =
|
43
|
+
const getEntryObject = () => {
|
44
|
+
const result = new ConfigObject()
|
43
45
|
const glob = getExtensionsGlob()
|
44
46
|
const rootPath = join(config.source_path, config.source_entry_path)
|
45
47
|
const paths = sync(join(rootPath, glob))
|
46
48
|
paths.forEach((path) => {
|
47
49
|
const namespace = relative(join(rootPath), dirname(path))
|
48
50
|
const name = join(namespace, basename(path, extname(path)))
|
49
|
-
result
|
51
|
+
result.set(name, resolve(path))
|
50
52
|
})
|
51
53
|
return result
|
52
54
|
}
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
+
const getModulePaths = () => {
|
57
|
+
const result = new ConfigList()
|
58
|
+
result.append('source', resolve(config.source_path))
|
59
|
+
result.append('node_modules', 'node_modules')
|
56
60
|
if (config.resolved_paths) {
|
57
|
-
|
61
|
+
config.resolved_paths.forEach(path => result.append(basename(path), path))
|
58
62
|
}
|
59
63
|
return result
|
60
64
|
}
|
61
65
|
|
66
|
+
const getBaseConfig = () =>
|
67
|
+
new ConfigObject({
|
68
|
+
output: {
|
69
|
+
filename: '[name]-[chunkhash].js',
|
70
|
+
chunkFilename: '[name]-[chunkhash].chunk.js',
|
71
|
+
path: assetHost.path,
|
72
|
+
publicPath: assetHost.publicPath
|
73
|
+
},
|
74
|
+
|
75
|
+
resolve: {
|
76
|
+
extensions: config.extensions
|
77
|
+
},
|
78
|
+
|
79
|
+
resolveLoader: {
|
80
|
+
modules: ['node_modules']
|
81
|
+
},
|
82
|
+
|
83
|
+
node: {
|
84
|
+
dgram: 'empty',
|
85
|
+
fs: 'empty',
|
86
|
+
net: 'empty',
|
87
|
+
tls: 'empty',
|
88
|
+
child_process: 'empty'
|
89
|
+
}
|
90
|
+
})
|
91
|
+
|
62
92
|
module.exports = class Environment {
|
63
93
|
constructor() {
|
64
|
-
this.loaders =
|
65
|
-
this.plugins =
|
94
|
+
this.loaders = getLoaderList()
|
95
|
+
this.plugins = getPluginList()
|
96
|
+
this.config = getBaseConfig()
|
97
|
+
this.entry = getEntryObject()
|
98
|
+
this.resolvedModules = getModulePaths()
|
66
99
|
}
|
67
100
|
|
68
101
|
toWebpackConfig() {
|
69
|
-
return {
|
70
|
-
entry:
|
71
|
-
|
72
|
-
output: {
|
73
|
-
filename: '[name]-[chunkhash].js',
|
74
|
-
chunkFilename: '[name]-[chunkhash].chunk.js',
|
75
|
-
path: assetHost.path,
|
76
|
-
publicPath: assetHost.publicPath
|
77
|
-
},
|
102
|
+
return this.config.merge({
|
103
|
+
entry: this.entry.toObject(),
|
78
104
|
|
79
105
|
module: {
|
80
|
-
|
106
|
+
strictExportPresence: true,
|
107
|
+
rules: [
|
108
|
+
{ oneOf: this.loaders.values() }
|
109
|
+
]
|
81
110
|
},
|
82
111
|
|
83
|
-
plugins:
|
112
|
+
plugins: this.plugins.values(),
|
84
113
|
|
85
114
|
resolve: {
|
86
|
-
|
87
|
-
modules: getModulePaths()
|
88
|
-
},
|
89
|
-
|
90
|
-
resolveLoader: {
|
91
|
-
modules: ['node_modules']
|
115
|
+
modules: this.resolvedModules.values()
|
92
116
|
}
|
93
|
-
}
|
117
|
+
})
|
94
118
|
}
|
95
119
|
}
|
@@ -8,43 +8,40 @@ module.exports = class extends Environment {
|
|
8
8
|
super()
|
9
9
|
|
10
10
|
if (devServer.hmr) {
|
11
|
-
this.plugins.
|
12
|
-
this.plugins.
|
11
|
+
this.plugins.append('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
|
12
|
+
this.plugins.append('NamedModules', new webpack.NamedModulesPlugin())
|
13
|
+
this.config.output.filename = '[name]-[hash].js'
|
13
14
|
}
|
14
|
-
}
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
}
|
21
|
-
result.output.pathinfo = true
|
22
|
-
result.devtool = 'cheap-eval-source-map'
|
23
|
-
result.devServer = {
|
24
|
-
clientLogLevel: 'none',
|
25
|
-
compress: true,
|
26
|
-
disableHostCheck: devServer.disable_host_check,
|
27
|
-
host: devServer.host,
|
28
|
-
port: devServer.port,
|
29
|
-
https: devServer.https,
|
30
|
-
hot: devServer.hmr,
|
31
|
-
contentBase: assetHost.path,
|
32
|
-
inline: devServer.inline,
|
33
|
-
useLocalIp: devServer.use_local_ip,
|
34
|
-
public: devServer.public,
|
35
|
-
publicPath: assetHost.publicPath,
|
36
|
-
historyApiFallback: true,
|
37
|
-
headers: {
|
38
|
-
'Access-Control-Allow-Origin': '*'
|
16
|
+
this.config.merge({
|
17
|
+
devtool: 'cheap-module-source-map',
|
18
|
+
output: {
|
19
|
+
pathinfo: true
|
39
20
|
},
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
21
|
+
devServer: {
|
22
|
+
clientLogLevel: 'none',
|
23
|
+
compress: devServer.compress,
|
24
|
+
quiet: devServer.quiet,
|
25
|
+
disableHostCheck: devServer.disable_host_check,
|
26
|
+
host: devServer.host,
|
27
|
+
port: devServer.port,
|
28
|
+
https: devServer.https,
|
29
|
+
hot: devServer.hmr,
|
30
|
+
contentBase: assetHost.path,
|
31
|
+
inline: devServer.inline,
|
32
|
+
useLocalIp: devServer.use_local_ip,
|
33
|
+
public: devServer.public,
|
34
|
+
publicPath: assetHost.publicPath,
|
35
|
+
historyApiFallback: {
|
36
|
+
disableDotRule: true
|
37
|
+
},
|
38
|
+
headers: devServer.headers,
|
39
|
+
overlay: devServer.overlay,
|
40
|
+
stats: {
|
41
|
+
errorDetails: true
|
42
|
+
},
|
43
|
+
watchOptions: devServer.watch_options
|
46
44
|
}
|
47
|
-
}
|
48
|
-
return result
|
45
|
+
})
|
49
46
|
}
|
50
47
|
}
|
@@ -6,29 +6,32 @@ module.exports = class extends Environment {
|
|
6
6
|
constructor() {
|
7
7
|
super()
|
8
8
|
|
9
|
-
this.plugins.
|
9
|
+
this.plugins.append('ModuleConcatenation', new webpack.optimize.ModuleConcatenationPlugin())
|
10
10
|
|
11
|
-
this.plugins.
|
11
|
+
this.plugins.append('UglifyJs', new webpack.optimize.UglifyJsPlugin({
|
12
12
|
sourceMap: true,
|
13
|
+
mangle: {
|
14
|
+
safari10: true
|
15
|
+
},
|
13
16
|
compress: {
|
14
|
-
warnings: false
|
17
|
+
warnings: false,
|
18
|
+
comparisons: false
|
15
19
|
},
|
16
20
|
output: {
|
17
|
-
comments: false
|
21
|
+
comments: false,
|
22
|
+
ascii_only: true
|
18
23
|
}
|
19
24
|
}))
|
20
25
|
|
21
|
-
this.plugins.
|
26
|
+
this.plugins.append('Compression', new CompressionPlugin({
|
22
27
|
asset: '[path].gz[query]',
|
23
28
|
algorithm: 'gzip',
|
24
29
|
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
|
25
30
|
}))
|
26
|
-
}
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
return result
|
32
|
+
this.config.merge({
|
33
|
+
devtool: 'nosources-source-map',
|
34
|
+
stats: 'normal'
|
35
|
+
})
|
33
36
|
}
|
34
37
|
}
|
data/package/index.js
CHANGED
@@ -4,8 +4,11 @@
|
|
4
4
|
const { resolve } = require('path')
|
5
5
|
const { existsSync } = require('fs')
|
6
6
|
const Environment = require('./environment')
|
7
|
+
const config = require('./config')
|
8
|
+
const assetHost = require('./asset_host')
|
9
|
+
const loaders = require('./rules')
|
7
10
|
|
8
|
-
|
11
|
+
const createEnvironment = () => {
|
9
12
|
const path = resolve(__dirname, 'environments', `${process.env.NODE_ENV}.js`)
|
10
13
|
const constructor = existsSync(path) ? require(path) : Environment
|
11
14
|
return new constructor()
|
@@ -13,4 +16,6 @@ function createEnvironment() {
|
|
13
16
|
|
14
17
|
const environment = createEnvironment()
|
15
18
|
|
16
|
-
module.exports = {
|
19
|
+
module.exports = {
|
20
|
+
environment, config, assetHost, loaders, Environment
|
21
|
+
}
|
@@ -4,8 +4,10 @@ const { cache_path } = require('../config')
|
|
4
4
|
module.exports = {
|
5
5
|
test: /\.(js|jsx)?(\.erb)?$/,
|
6
6
|
exclude: /node_modules/,
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
use: [{
|
8
|
+
loader: 'babel-loader',
|
9
|
+
options: {
|
10
|
+
cacheDirectory: join(cache_path, 'babel-loader')
|
11
|
+
}
|
12
|
+
}]
|
11
13
|
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
2
|
+
const path = require('path')
|
3
|
+
const { dev_server: devServer } = require('../config')
|
4
|
+
|
5
|
+
const postcssConfigPath = path.resolve(process.cwd(), '.postcssrc.yml')
|
6
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
7
|
+
const inDevServer = process.argv.find(v => v.includes('webpack-dev-server'))
|
8
|
+
const isHMR = inDevServer && (devServer && devServer.hmr)
|
9
|
+
const extractCSS = !(isHMR) || isProduction
|
10
|
+
|
11
|
+
const styleLoader = {
|
12
|
+
loader: 'style-loader',
|
13
|
+
options: {
|
14
|
+
hmr: isHMR,
|
15
|
+
sourceMap: true
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
const extractOptions = {
|
20
|
+
fallback: styleLoader,
|
21
|
+
use: [
|
22
|
+
{ loader: 'css-loader', options: { minimize: isProduction, sourceMap: true, importLoaders: 2 } },
|
23
|
+
{ loader: 'postcss-loader', options: { sourceMap: true, config: { path: postcssConfigPath } } }
|
24
|
+
]
|
25
|
+
}
|
26
|
+
|
27
|
+
// For production extract styles to a separate bundle
|
28
|
+
const extractCSSLoader = {
|
29
|
+
test: /\.(css)$/i,
|
30
|
+
use: ExtractTextPlugin.extract(extractOptions)
|
31
|
+
}
|
32
|
+
|
33
|
+
// For hot-reloading use regular loaders
|
34
|
+
const inlineCSSLoader = {
|
35
|
+
test: /\.(css)$/i,
|
36
|
+
use: [styleLoader].concat(extractOptions.use)
|
37
|
+
}
|
38
|
+
|
39
|
+
module.exports = extractCSS ? extractCSSLoader : inlineCSSLoader
|
@@ -0,0 +1,23 @@
|
|
1
|
+
const { resolve } = require('path')
|
2
|
+
|
3
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
4
|
+
const elmSource = resolve(process.cwd())
|
5
|
+
const elmMake = `${elmSource}/node_modules/.bin/elm-make`
|
6
|
+
|
7
|
+
const elmDefaultOptions = { cwd: elmSource, pathToMake: elmMake }
|
8
|
+
const developmentOptions = Object.assign(elmDefaultOptions, {
|
9
|
+
verbose: true,
|
10
|
+
warn: true,
|
11
|
+
debug: true
|
12
|
+
})
|
13
|
+
|
14
|
+
const elmWebpackLoader = {
|
15
|
+
loader: 'elm-webpack-loader',
|
16
|
+
options: isProduction ? elmDefaultOptions : developmentOptions
|
17
|
+
}
|
18
|
+
|
19
|
+
module.exports = {
|
20
|
+
test: /\.elm(\.erb)?$/,
|
21
|
+
exclude: [/elm-stuff/, /node_modules/],
|
22
|
+
use: isProduction ? [elmWebpackLoader] : [{ loader: 'elm-hot-loader' }, elmWebpackLoader]
|
23
|
+
}
|