webpacker 3.2.2 → 3.3.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 +21 -1
- data/Gemfile.lock +38 -38
- data/README.md +48 -49
- data/docs/css.md +31 -1
- data/docs/docker.md +1 -1
- data/docs/typescript.md +36 -1
- data/{exe → lib/install/bin}/webpack +7 -0
- data/{exe → lib/install/bin}/webpack-dev-server +7 -0
- data/lib/install/binstubs.rb +4 -0
- data/lib/install/config/webpacker.yml +3 -0
- data/lib/install/loaders/erb.js +1 -1
- data/lib/install/template.rb +1 -2
- data/lib/install/typescript.rb +1 -1
- data/lib/tasks/webpacker.rake +1 -0
- data/lib/tasks/webpacker/binstubs.rake +12 -0
- data/lib/tasks/webpacker/check_binstubs.rake +1 -1
- data/lib/webpacker.rb +1 -0
- data/lib/webpacker/compiler.rb +4 -2
- data/lib/webpacker/dev_server_runner.rb +1 -1
- data/lib/webpacker/env.rb +39 -0
- data/lib/webpacker/instance.rb +1 -12
- data/lib/webpacker/version.rb +1 -1
- data/package.json +2 -2
- data/package/__tests__/config.js +7 -4
- data/package/__tests__/dev_server.js +26 -0
- data/package/__tests__/env.js +28 -0
- data/package/__tests__/index.js +31 -0
- data/package/config.js +14 -30
- data/package/config_types/__tests__/config_list.js +0 -5
- data/package/config_types/config_list.js +0 -9
- data/package/dev_server.js +23 -0
- data/package/env.js +23 -0
- data/package/{__tests__/environment.js → environments/__tests__/base.js} +6 -6
- data/package/{environment.js → environments/base.js} +4 -4
- data/package/environments/development.js +4 -3
- data/package/environments/production.js +31 -25
- data/package/environments/test.js +2 -2
- data/package/index.js +10 -6
- data/package/rules/babel.js +8 -6
- data/package/rules/css.js +2 -38
- data/package/rules/file.js +9 -7
- data/package/rules/index.js +4 -0
- data/package/rules/module.css.js +3 -0
- data/package/rules/module.sass.js +8 -0
- data/package/rules/sass.js +5 -12
- data/package/utils/__tests__/get_style_rule.js +36 -0
- data/package/utils/get_style_rule.js +62 -0
- data/package/utils/helpers.js +17 -3
- data/test/env_test.rb +19 -0
- data/test/test_app/bin/webpack +15 -0
- data/test/test_app/bin/webpack-dev-server +15 -0
- data/test/test_app/config/webpacker.yml +3 -0
- data/test/test_helper.rb +3 -1
- data/webpacker.gemspec +0 -2
- data/yarn.lock +8 -4
- metadata +26 -10
@@ -8,11 +8,6 @@ test('new', () => {
|
|
8
8
|
expect(list).toBeInstanceOf(Array)
|
9
9
|
})
|
10
10
|
|
11
|
-
test('set', () => {
|
12
|
-
const list = new ConfigList()
|
13
|
-
expect(list.set('key', 'value')).toEqual([{ key: 'key', value: 'value' }])
|
14
|
-
})
|
15
|
-
|
16
11
|
test('get', () => {
|
17
12
|
const list = new ConfigList()
|
18
13
|
list.append('key', 'value')
|
@@ -10,15 +10,6 @@ class ConfigList extends Array {
|
|
10
10
|
return this[index].value
|
11
11
|
}
|
12
12
|
|
13
|
-
/**
|
14
|
-
* @deprecated after the 3.0.2 release and will be removed in the next major release
|
15
|
-
*/
|
16
|
-
set(key, value) {
|
17
|
-
/* eslint no-console: 0 */
|
18
|
-
console.warn('set is deprecated! Use append instead')
|
19
|
-
return this.append(key, value)
|
20
|
-
}
|
21
|
-
|
22
13
|
append(key, value) {
|
23
14
|
return this.add({ key, value })
|
24
15
|
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
const { isBoolean, isEmpty } = require('./utils/helpers')
|
2
|
+
const config = require('./config')
|
3
|
+
|
4
|
+
const fetch = (key) => {
|
5
|
+
const value = process.env[key]
|
6
|
+
return isBoolean(value) ? JSON.parse(value) : value
|
7
|
+
}
|
8
|
+
|
9
|
+
const devServer = () => {
|
10
|
+
const devServerConfig = config.dev_server
|
11
|
+
|
12
|
+
if (devServerConfig) {
|
13
|
+
Object.keys(devServerConfig).forEach((key) => {
|
14
|
+
const envValue = fetch(`WEBPACKER_DEV_SERVER_${key.toUpperCase().replace(/_/g, '')}`)
|
15
|
+
if (isEmpty(envValue)) return devServerConfig[key]
|
16
|
+
devServerConfig[key] = envValue
|
17
|
+
})
|
18
|
+
}
|
19
|
+
|
20
|
+
return devServerConfig || {}
|
21
|
+
}
|
22
|
+
|
23
|
+
module.exports = devServer()
|
data/package/env.js
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
const { resolve } = require('path')
|
2
|
+
const { safeLoad } = require('js-yaml')
|
3
|
+
const { readFileSync } = require('fs')
|
4
|
+
|
5
|
+
const configPath = resolve('config', 'webpacker.yml')
|
6
|
+
const DEFAULT_ENV = 'production'
|
7
|
+
|
8
|
+
const env = () => {
|
9
|
+
const nodeEnv = process.env.NODE_ENV
|
10
|
+
const railsEnv = process.env.RAILS_ENV
|
11
|
+
const config = safeLoad(readFileSync(configPath), 'utf8')
|
12
|
+
const availableEnvironments = Object.keys(config).join('|')
|
13
|
+
const regex = new RegExp(availableEnvironments, 'g')
|
14
|
+
|
15
|
+
if (nodeEnv && nodeEnv.match(regex)) return nodeEnv
|
16
|
+
if (railsEnv && railsEnv.match(regex)) return railsEnv
|
17
|
+
|
18
|
+
/* eslint no-console: 0 */
|
19
|
+
console.warn(`NODE_ENV=${nodeEnv} and RAILS_ENV=${railsEnv} environment is not defined in config/webpacker.yml, falling back to ${DEFAULT_ENV}`)
|
20
|
+
return DEFAULT_ENV
|
21
|
+
}
|
22
|
+
|
23
|
+
module.exports = env()
|
@@ -3,14 +3,14 @@
|
|
3
3
|
// environment.js expects to find config/webpacker.yml and resolved modules from
|
4
4
|
// the root of a Rails project
|
5
5
|
|
6
|
-
const
|
7
|
-
|
8
|
-
|
6
|
+
const { chdirTestApp, chdirCwd } = require('../../utils/helpers')
|
7
|
+
|
8
|
+
chdirTestApp()
|
9
9
|
|
10
10
|
const { resolve } = require('path')
|
11
|
-
const rules = require('
|
12
|
-
const { ConfigList } = require('
|
13
|
-
const Environment = require('../
|
11
|
+
const rules = require('../../rules')
|
12
|
+
const { ConfigList } = require('../../config_types')
|
13
|
+
const Environment = require('../base')
|
14
14
|
|
15
15
|
describe('Environment', () => {
|
16
16
|
afterAll(chdirCwd)
|
@@ -12,9 +12,9 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
|
12
12
|
const ManifestPlugin = require('webpack-manifest-plugin')
|
13
13
|
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
|
14
14
|
|
15
|
-
const { ConfigList, ConfigObject } = require('
|
16
|
-
const rules = require('
|
17
|
-
const config = require('
|
15
|
+
const { ConfigList, ConfigObject } = require('../config_types')
|
16
|
+
const rules = require('../rules')
|
17
|
+
const config = require('../config')
|
18
18
|
|
19
19
|
const getLoaderList = () => {
|
20
20
|
const result = new ConfigList()
|
@@ -85,7 +85,7 @@ const getBaseConfig = () =>
|
|
85
85
|
}
|
86
86
|
})
|
87
87
|
|
88
|
-
module.exports = class
|
88
|
+
module.exports = class Base {
|
89
89
|
constructor() {
|
90
90
|
this.loaders = getLoaderList()
|
91
91
|
this.plugins = getPluginList()
|
@@ -1,8 +1,9 @@
|
|
1
1
|
const webpack = require('webpack')
|
2
|
-
const
|
3
|
-
const
|
2
|
+
const Base = require('./base')
|
3
|
+
const devServer = require('../dev_server')
|
4
|
+
const { outputPath: contentBase, publicPath } = require('../config')
|
4
5
|
|
5
|
-
module.exports = class extends
|
6
|
+
module.exports = class extends Base {
|
6
7
|
constructor() {
|
7
8
|
super()
|
8
9
|
|
@@ -1,40 +1,46 @@
|
|
1
1
|
const webpack = require('webpack')
|
2
2
|
const CompressionPlugin = require('compression-webpack-plugin')
|
3
3
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
4
|
-
const
|
4
|
+
const Base = require('./base')
|
5
5
|
|
6
|
-
module.exports = class extends
|
6
|
+
module.exports = class extends Base {
|
7
7
|
constructor() {
|
8
8
|
super()
|
9
9
|
|
10
10
|
this.plugins.append('ModuleConcatenation', new webpack.optimize.ModuleConcatenationPlugin())
|
11
11
|
|
12
|
-
this.plugins.append(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
safari10: true
|
22
|
-
},
|
23
|
-
compress: {
|
12
|
+
this.plugins.append(
|
13
|
+
'UglifyJs',
|
14
|
+
new UglifyJsPlugin({
|
15
|
+
parallel: true,
|
16
|
+
cache: true,
|
17
|
+
sourceMap: true,
|
18
|
+
uglifyOptions: {
|
19
|
+
ie8: false,
|
20
|
+
ecma: 8,
|
24
21
|
warnings: false,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
mangle: {
|
23
|
+
safari10: true
|
24
|
+
},
|
25
|
+
compress: {
|
26
|
+
warnings: false,
|
27
|
+
comparisons: false
|
28
|
+
},
|
29
|
+
output: {
|
30
|
+
ascii_only: true
|
31
|
+
}
|
29
32
|
}
|
30
|
-
}
|
31
|
-
|
33
|
+
})
|
34
|
+
)
|
32
35
|
|
33
|
-
this.plugins.append(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
this.plugins.append(
|
37
|
+
'Compression',
|
38
|
+
new CompressionPlugin({
|
39
|
+
asset: '[path].gz[query]',
|
40
|
+
algorithm: 'gzip',
|
41
|
+
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
|
42
|
+
})
|
43
|
+
)
|
38
44
|
|
39
45
|
this.config.merge({
|
40
46
|
devtool: 'nosources-source-map',
|
@@ -1,3 +1,3 @@
|
|
1
|
-
const
|
1
|
+
const Base = require('./base')
|
2
2
|
|
3
|
-
module.exports = class extends
|
3
|
+
module.exports = class extends Base {}
|
data/package/index.js
CHANGED
@@ -3,18 +3,22 @@
|
|
3
3
|
|
4
4
|
const { resolve } = require('path')
|
5
5
|
const { existsSync } = require('fs')
|
6
|
-
const Environment = require('./
|
7
|
-
const config = require('./config')
|
6
|
+
const Environment = require('./environments/base')
|
8
7
|
const loaders = require('./rules')
|
8
|
+
const env = require('./env')
|
9
|
+
const config = require('./config')
|
10
|
+
const devServer = require('./dev_server')
|
9
11
|
|
10
12
|
const createEnvironment = () => {
|
11
|
-
const path = resolve(__dirname, 'environments', `${
|
13
|
+
const path = resolve(__dirname, 'environments', `${env}.js`)
|
12
14
|
const constructor = existsSync(path) ? require(path) : Environment
|
13
15
|
return new constructor()
|
14
16
|
}
|
15
17
|
|
16
|
-
const environment = createEnvironment()
|
17
|
-
|
18
18
|
module.exports = {
|
19
|
-
|
19
|
+
config,
|
20
|
+
devServer,
|
21
|
+
environment: createEnvironment(),
|
22
|
+
Environment,
|
23
|
+
loaders
|
20
24
|
}
|
data/package/rules/babel.js
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
const { join } = require('path')
|
2
|
-
const { cache_path } = require('../config')
|
2
|
+
const { cache_path: cachePath } = require('../config')
|
3
3
|
|
4
4
|
module.exports = {
|
5
5
|
test: /\.(js|jsx)?(\.erb)?$/,
|
6
6
|
exclude: /node_modules/,
|
7
|
-
use: [
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
use: [
|
8
|
+
{
|
9
|
+
loader: 'babel-loader',
|
10
|
+
options: {
|
11
|
+
cacheDirectory: join(cachePath, 'babel-loader')
|
12
|
+
}
|
11
13
|
}
|
12
|
-
|
14
|
+
]
|
13
15
|
}
|
data/package/rules/css.js
CHANGED
@@ -1,39 +1,3 @@
|
|
1
|
-
const
|
2
|
-
const path = require('path')
|
3
|
-
const { dev_server: devServer } = require('../config')
|
1
|
+
const getStyleRule = require('../utils/get_style_rule')
|
4
2
|
|
5
|
-
|
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
|
3
|
+
module.exports = getStyleRule(/\.(css)$/i)
|
data/package/rules/file.js
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
const { join } = require('path')
|
2
|
-
const { source_path } = require('../config')
|
2
|
+
const { source_path: sourcePath } = require('../config')
|
3
3
|
|
4
4
|
module.exports = {
|
5
5
|
test: /\.(jpg|jpeg|png|gif|tiff|ico|svg|eot|otf|ttf|woff|woff2)$/i,
|
6
|
-
use: [
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
use: [
|
7
|
+
{
|
8
|
+
loader: 'file-loader',
|
9
|
+
options: {
|
10
|
+
name: '[path][name]-[hash].[ext]',
|
11
|
+
context: join(sourcePath)
|
12
|
+
}
|
11
13
|
}
|
12
|
-
|
14
|
+
]
|
13
15
|
}
|
data/package/rules/index.js
CHANGED
@@ -2,10 +2,14 @@ const babel = require('./babel')
|
|
2
2
|
const file = require('./file')
|
3
3
|
const css = require('./css')
|
4
4
|
const sass = require('./sass')
|
5
|
+
const moduleCss = require('./module.css')
|
6
|
+
const moduleSass = require('./module.sass')
|
5
7
|
|
6
8
|
module.exports = {
|
7
9
|
babel,
|
8
10
|
css,
|
9
11
|
sass,
|
12
|
+
moduleCss,
|
13
|
+
moduleSass,
|
10
14
|
file
|
11
15
|
}
|
data/package/rules/sass.js
CHANGED
@@ -1,15 +1,8 @@
|
|
1
|
-
const
|
2
|
-
const deepMerge = require('../utils/deep_merge')
|
1
|
+
const getStyleRule = require('../utils/get_style_rule')
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
sassLoader = deepMerge(sassLoader, {
|
8
|
-
test: /\.(scss|sass)$/i,
|
9
|
-
use: [{
|
3
|
+
module.exports = getStyleRule(/\.(scss|sass)$/i, false, [
|
4
|
+
{
|
10
5
|
loader: 'sass-loader',
|
11
6
|
options: { sourceMap: true }
|
12
|
-
}
|
13
|
-
|
14
|
-
|
15
|
-
module.exports = sassLoader
|
7
|
+
}
|
8
|
+
])
|
@@ -0,0 +1,36 @@
|
|
1
|
+
const { chdirTestApp, chdirCwd } = require('../helpers')
|
2
|
+
|
3
|
+
chdirTestApp()
|
4
|
+
|
5
|
+
const getStyleRule = require('../get_style_rule')
|
6
|
+
|
7
|
+
describe('getStyleRule', () => {
|
8
|
+
afterAll(chdirCwd)
|
9
|
+
|
10
|
+
test('excludes modules by default', () => {
|
11
|
+
const cssRule = getStyleRule(/\.(css)$/i)
|
12
|
+
const expectation = {
|
13
|
+
test: /\.(css)$/i,
|
14
|
+
exclude: /\.module\.[a-z]+$/
|
15
|
+
}
|
16
|
+
|
17
|
+
expect(cssRule).toMatchObject(expectation)
|
18
|
+
})
|
19
|
+
|
20
|
+
test('includes modules if set to true', () => {
|
21
|
+
const cssRule = getStyleRule(/\.(scss)$/i, true)
|
22
|
+
const expectation = {
|
23
|
+
test: /\.(scss)$/i,
|
24
|
+
include: /\.module\.[a-z]+$/
|
25
|
+
}
|
26
|
+
|
27
|
+
expect(cssRule).toMatchObject(expectation)
|
28
|
+
})
|
29
|
+
|
30
|
+
test('adds extra preprocessors if supplied', () => {
|
31
|
+
const expectation = [{ foo: 'bar' }]
|
32
|
+
const cssRule = getStyleRule(/\.(css)$/i, true, expectation)
|
33
|
+
|
34
|
+
expect(cssRule.use).toMatchObject(expect.arrayContaining(expectation))
|
35
|
+
})
|
36
|
+
})
|
@@ -0,0 +1,62 @@
|
|
1
|
+
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
2
|
+
const path = require('path')
|
3
|
+
const devServer = require('../dev_server')
|
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 getStyleRule = (test, modules = false, preprocessors = []) => {
|
20
|
+
const extractOptions = {
|
21
|
+
fallback: styleLoader,
|
22
|
+
use: [
|
23
|
+
{
|
24
|
+
loader: 'css-loader',
|
25
|
+
options: {
|
26
|
+
minimize: isProduction,
|
27
|
+
sourceMap: true,
|
28
|
+
importLoaders: 2,
|
29
|
+
modules
|
30
|
+
}
|
31
|
+
},
|
32
|
+
{
|
33
|
+
loader: 'postcss-loader',
|
34
|
+
options: {
|
35
|
+
sourceMap: true,
|
36
|
+
config: { path: postcssConfigPath }
|
37
|
+
}
|
38
|
+
},
|
39
|
+
...preprocessors
|
40
|
+
]
|
41
|
+
}
|
42
|
+
|
43
|
+
const options = modules ? { include: /\.module\.[a-z]+$/ } : { exclude: /\.module\.[a-z]+$/ }
|
44
|
+
|
45
|
+
// For production extract styles to a separate bundle
|
46
|
+
const extractCSSLoader = Object.assign(
|
47
|
+
{},
|
48
|
+
{ test, use: ExtractTextPlugin.extract(extractOptions) },
|
49
|
+
options
|
50
|
+
)
|
51
|
+
|
52
|
+
// For hot-reloading use regular loaders
|
53
|
+
const inlineCSSLoader = Object.assign(
|
54
|
+
{},
|
55
|
+
{ test, use: [styleLoader].concat(extractOptions.use) },
|
56
|
+
options
|
57
|
+
)
|
58
|
+
|
59
|
+
return extractCSS ? extractCSSLoader : inlineCSSLoader
|
60
|
+
}
|
61
|
+
|
62
|
+
module.exports = getStyleRule
|