Skip to content

Commit 8803126

Browse files
author
Robert Mosolgo
authored
Merge pull request #722 from asaletnik/railtie_fix
Update Railtie file_watcher / reloaders implementation
2 parents b69c9ce + a27637b commit 8803126

20 files changed

+580
-249
lines changed

lib/react/rails/railtie.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ class Railtie < ::Rails::Railtie
3333
end
3434

3535
# Rails checks these objects for changes:
36-
app.reloaders << app.config.file_watcher.new([], reload_paths) {}
36+
react_reloader = app.config.file_watcher.new([], reload_paths) do
37+
React::ServerRendering.reset_pool
38+
end
39+
app.reloaders << react_reloader
40+
3741
# Reload renderers in dev when files change
38-
config.to_prepare { React::ServerRendering.reset_pool }
42+
config.to_prepare { react_reloader.execute_if_updated }
3943
end
4044

4145
# Include the react-rails view helper lazily

test/dummy/.babelrc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
11
{
2-
"presets": ["env", "react"]
2+
"presets": [
3+
[
4+
"env",
5+
{
6+
"modules": false,
7+
"targets": {
8+
"browsers": "> 1%",
9+
"uglify": true
10+
},
11+
"useBuiltIns": true
12+
}
13+
],
14+
"react"
15+
]
316
}

test/dummy/bin/webpack

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,28 @@ require "shellwords"
55
require "yaml"
66

77
ENV["RAILS_ENV"] ||= "development"
8-
RAILS_ENV = ENV["RAILS_ENV"]
8+
RAILS_ENV = ENV["RAILS_ENV"]
99

1010
ENV["NODE_ENV"] ||= RAILS_ENV
11-
NODE_ENV = ENV["NODE_ENV"]
11+
NODE_ENV = ENV["NODE_ENV"]
1212

13-
APP_PATH = File.expand_path("../", __dir__)
14-
CONFIG_PATH = File.join(APP_PATH, "config/webpack/paths.yml")
15-
DEV_SERVER_CONFIG_PATH = File.join(APP_PATH, "config/webpack/development.server.yml")
13+
APP_PATH = File.expand_path("../", __dir__)
1614

17-
begin
18-
paths = YAML.load(File.read(CONFIG_PATH))[NODE_ENV]
19-
dev_server = YAML.load(File.read(DEV_SERVER_CONFIG_PATH))[NODE_ENV]
20-
21-
NODE_MODULES_PATH = File.join(APP_PATH.shellescape, paths["node_modules"])
22-
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, paths["config"])
23-
24-
if NODE_ENV == "development" && dev_server["enabled"]
25-
puts "Warning: webpack-dev-server is currently enabled in #{DEV_SERVER_CONFIG_PATH}. " \
26-
"Disable to serve assets directly from public/packs directory"
27-
end
15+
def load_yaml_config(config_file)
16+
YAML.load_file(File.join(APP_PATH, config_file))[NODE_ENV]
2817
rescue Errno::ENOENT, NoMethodError
29-
puts "Configuration not found in config/webpack/paths.yml or config/webpack/development.server.yml."
18+
puts "Configuration not found in #{config_file}."
3019
puts "Please run bundle exec rails webpacker:install to install webpacker"
3120
exit!
3221
end
3322

34-
WEBPACK_BIN = "#{NODE_MODULES_PATH}/.bin/webpack"
35-
WEBPACK_CONFIG = "#{WEBPACK_CONFIG_PATH}/#{NODE_ENV}.js"
23+
paths = load_yaml_config("config/webpack/paths.yml")
24+
NODE_MODULES_PATH = File.join(APP_PATH, paths["node_modules"])
25+
WEBPACK_CONFIG = File.join(APP_PATH, paths["config"], "#{NODE_ENV}.js")
26+
27+
newenv = { "NODE_PATH" => NODE_MODULES_PATH.shellescape }
28+
cmdline = ["yarn", "run", "webpack", "--", "--config", WEBPACK_CONFIG] + ARGV
3629

3730
Dir.chdir(APP_PATH) do
38-
exec "NODE_PATH=#{NODE_MODULES_PATH} #{WEBPACK_BIN} --config #{WEBPACK_CONFIG}" \
39-
" #{ARGV.join(" ")}"
31+
exec newenv, *cmdline
4032
end

test/dummy/bin/webpack-dev-server

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,26 @@ RAILS_ENV = ENV["RAILS_ENV"]
1010
ENV["NODE_ENV"] ||= RAILS_ENV
1111
NODE_ENV = ENV["NODE_ENV"]
1212

13-
APP_PATH = File.expand_path("../", __dir__)
14-
CONFIG_PATH = File.join(APP_PATH, "config/webpack/paths.yml")
13+
APP_PATH = File.expand_path("../", __dir__)
1514

16-
begin
17-
paths = YAML.load(File.read(CONFIG_PATH))[NODE_ENV]
18-
19-
NODE_MODULES_PATH = File.join(APP_PATH.shellescape, paths["node_modules"])
20-
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, paths["config"])
21-
22-
WEBPACK_BIN = "#{NODE_MODULES_PATH}/.bin/webpack-dev-server"
23-
DEV_SERVER_CONFIG = "#{WEBPACK_CONFIG_PATH}/development.server.js"
15+
def load_yaml_config(config_file)
16+
YAML.load_file(File.join(APP_PATH, config_file))[NODE_ENV]
2417
rescue Errno::ENOENT, NoMethodError
25-
puts "Configuration not found in config/webpacker/paths.yml."
18+
puts "Configuration not found in #{config_file}."
2619
puts "Please run bundle exec rails webpacker:install to install webpacker"
2720
exit!
2821
end
2922

23+
paths = load_yaml_config("config/webpack/paths.yml")
24+
NODE_MODULES_PATH = File.join(APP_PATH, paths["node_modules"])
25+
WEBPACK_CONFIG = File.join(APP_PATH, paths["config"], "development.server.js")
26+
27+
dev_server = load_yaml_config("config/webpack/development.server.yml")
28+
DEV_SERVER_HOST = "http#{"s" if dev_server["https"]}://#{dev_server["host"]}:#{dev_server["port"]}"
29+
30+
newenv = { "NODE_PATH" => NODE_MODULES_PATH.shellescape, "ASSET_HOST" => DEV_SERVER_HOST.shellescape }
31+
cmdline = ["yarn", "run", "webpack-dev-server", "--", "--progress", "--color", "--config", WEBPACK_CONFIG] + ARGV
32+
3033
Dir.chdir(APP_PATH) do
31-
exec "NODE_PATH=#{NODE_MODULES_PATH} #{WEBPACK_BIN} --progress --color " \
32-
"--config #{DEV_SERVER_CONFIG}"
34+
exec newenv, *cmdline
3335
end

test/dummy/config/webpack/configuration.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,29 @@ const configPath = resolve('config', 'webpack')
99
const loadersDir = join(__dirname, 'loaders')
1010
const paths = safeLoad(readFileSync(join(configPath, 'paths.yml'), 'utf8'))[env.NODE_ENV]
1111
const devServer = safeLoad(readFileSync(join(configPath, 'development.server.yml'), 'utf8'))[env.NODE_ENV]
12-
const publicPath = env.NODE_ENV !== 'production' && devServer.enabled ?
13-
`http://${devServer.host}:${devServer.port}/` : `/${paths.entry}/`
12+
13+
function removeOuterSlashes(string) {
14+
return string.replace(/^\/*/, '').replace(/\/*$/, '')
15+
}
16+
17+
function formatPublicPath(host = '', path = '') {
18+
let formattedHost = removeOuterSlashes(host)
19+
if (formattedHost && !/^http/i.test(formattedHost)) {
20+
formattedHost = `//${formattedHost}`
21+
}
22+
const formattedPath = removeOuterSlashes(path)
23+
return `${formattedHost}/${formattedPath}/`
24+
}
25+
26+
const output = {
27+
path: resolve('public', paths.output),
28+
publicPath: formatPublicPath(env.ASSET_HOST, paths.output)
29+
}
1430

1531
module.exports = {
1632
devServer,
1733
env,
1834
paths,
1935
loadersDir,
20-
publicPath
36+
output
2137
}

test/dummy/config/webpack/development.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Note: You must restart bin/webpack-watcher for changes to take effect
1+
// Note: You must restart bin/webpack-dev-server for changes to take effect
22

33
const merge = require('webpack-merge')
44
const sharedConfig = require('./shared.js')
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Note: You must restart bin/webpack-dev-server for changes to take effect
22

3-
const { resolve } = require('path')
43
const merge = require('webpack-merge')
54
const devConfig = require('./development.js')
6-
const { devServer, publicPath, paths } = require('./configuration.js')
5+
const { devServer, output } = require('./configuration.js')
76

87
module.exports = merge(devConfig, {
98
devServer: {
109
host: devServer.host,
1110
port: devServer.port,
11+
contentBase: output.path,
12+
publicPath: output.publicPath,
1213
compress: true,
13-
historyApiFallback: true,
14-
contentBase: resolve(paths.output, paths.entry),
15-
publicPath
14+
headers: { 'Access-Control-Allow-Origin': '*' },
15+
historyApiFallback: true
1616
}
1717
})

test/dummy/config/webpack/development.server.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Restart webpack-dev-server if you make changes here
1+
# Note: You must restart bin/webpack-dev-server for changes to take effect
2+
23
default: &default
34
enabled: true
45
host: localhost

test/dummy/config/webpack/loaders/assets.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const { env, publicPath } = require('../configuration.js')
22

33
module.exports = {
4-
test: /\.(jpeg|png|gif|svg|eot|ttf|woff|woff2)$/i,
4+
test: /\.(jpg|jpeg|png|gif|svg|eot|ttf|woff|woff2)$/i,
55
use: [{
66
loader: 'file-loader',
77
options: {
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
module.exports = {
22
test: /\.js(\.erb)?$/,
33
exclude: /node_modules/,
4-
loader: 'babel-loader',
5-
options: {
6-
presets: [
7-
['env', { modules: false }]
8-
]
9-
}
4+
loader: 'babel-loader'
105
}

test/dummy/config/webpack/loaders/erb.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ module.exports = {
44
exclude: /node_modules/,
55
loader: 'rails-erb-loader',
66
options: {
7-
runner: 'DISABLE_SPRING=1 bin/rails runner'
7+
runner: 'bin/rails runner'
88
}
99
}
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
module.exports = {
22
test: /\.(js|jsx)?(\.erb)?$/,
33
exclude: /node_modules/,
4-
loader: 'babel-loader',
5-
options: {
6-
presets: [
7-
'react',
8-
['env', { modules: false }]
9-
]
10-
}
4+
loader: 'babel-loader'
115
}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
const ExtractTextPlugin = require('extract-text-webpack-plugin')
2+
const { env } = require('../configuration.js')
23

34
module.exports = {
45
test: /\.(scss|sass|css)$/i,
56
use: ExtractTextPlugin.extract({
67
fallback: 'style-loader',
7-
use: ['css-loader', 'postcss-loader', 'sass-loader']
8+
use: [
9+
{ loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } },
10+
{ loader: 'postcss-loader', options: { sourceMap: true } },
11+
'resolve-url-loader',
12+
{ loader: 'sass-loader', options: { sourceMap: true } }
13+
]
814
})
915
}

test/dummy/config/webpack/paths.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
# Restart webpack-watcher or webpack-dev-server if you make changes here
2-
default: &default
3-
config: config/webpack
4-
entry: packs
5-
output: public
6-
manifest: manifest.json
7-
node_modules: node_modules
8-
source: app/javascript
1+
# Note: You must restart bin/webpack-dev-server for changes to take effect
2+
3+
default: &default # ~ = Rails.root
4+
source: app/javascript # ~/:source
5+
entry: packs # ~/:source/:entry
6+
output: packs # ~/public/:output
7+
manifest: manifest.json # ~/public/:output/:manifest
8+
config: config/webpack # ~/:config
9+
node_modules: node_modules # ~/:node_modules
910
extensions:
1011
- .coffee
1112
- .js
@@ -19,6 +20,7 @@ default: &default
1920
- .svg
2021
- .gif
2122
- .jpeg
23+
- .jpg
2224

2325
development:
2426
<<: *default

test/dummy/config/webpack/production.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
// Note: You must restart bin/webpack-dev-server for changes to take effect
2+
13
/* eslint global-require: 0 */
2-
// Note: You must run bin/webpack for changes to take effect
34

45
const webpack = require('webpack')
56
const merge = require('webpack-merge')
@@ -14,7 +15,7 @@ module.exports = merge(sharedConfig, {
1415
new CompressionPlugin({
1516
asset: '[path].gz[query]',
1617
algorithm: 'gzip',
17-
test: /\.(js|css|svg|eot|ttf|woff|woff2)$/
18+
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
1819
})
1920
]
2021
})

test/dummy/config/webpack/shared.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,47 @@
1-
// Note: You must restart bin/webpack-watcher for changes to take effect
1+
// Note: You must restart bin/webpack-dev-server for changes to take effect
2+
23
/* eslint global-require: 0 */
34
/* eslint import/no-dynamic-require: 0 */
45

56
const webpack = require('webpack')
6-
const { basename, join, resolve } = require('path')
7+
const { basename, dirname, join, relative, resolve } = require('path')
78
const { sync } = require('glob')
8-
const { readdirSync } = require('fs')
99
const ExtractTextPlugin = require('extract-text-webpack-plugin')
1010
const ManifestPlugin = require('webpack-manifest-plugin')
1111
const extname = require('path-complete-extname')
12-
const { env, paths, publicPath, loadersDir } = require('./configuration.js')
12+
const { env, paths, output, loadersDir } = require('./configuration.js')
1313

14-
const extensionGlob = `*{${paths.extensions.join(',')}}*`
14+
const extensionGlob = `**/*{${paths.extensions.join(',')}}*`
1515
const packPaths = sync(join(paths.source, paths.entry, extensionGlob))
1616

1717
module.exports = {
1818
entry: packPaths.reduce(
1919
(map, entry) => {
2020
const localMap = map
21-
localMap[basename(entry, extname(entry))] = resolve(entry)
21+
const namespace = relative(join(paths.source, paths.entry), dirname(entry))
22+
localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry)
2223
return localMap
2324
}, {}
2425
),
2526

26-
output: { filename: '[name].js', path: resolve(paths.output, paths.entry) },
27+
output: {
28+
filename: '[name].js',
29+
path: output.path,
30+
publicPath: output.publicPath
31+
},
2732

2833
module: {
29-
rules: readdirSync(loadersDir).map(file => (
30-
require(join(loadersDir, file))
31-
))
34+
rules: sync(join(loadersDir, '*.js')).map(loader => require(loader))
3235
},
3336

3437
plugins: [
3538
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
3639
new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
37-
new ManifestPlugin({ fileName: paths.manifest, publicPath, writeToFileEmit: true })
40+
new ManifestPlugin({
41+
fileName: paths.manifest,
42+
publicPath: output.publicPath,
43+
writeToFileEmit: true
44+
})
3845
],
3946

4047
resolve: {

test/dummy/config/webpack/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Note: You must restart bin/webpack-watcher for changes to take effect
1+
// Note: You must restart bin/webpack-dev-server for changes to take effect
22

33
const merge = require('webpack-merge')
44
const sharedConfig = require('./shared.js')

0 commit comments

Comments
 (0)