Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding dev server settings using env variables #843

Merged
merged 1 commit into from
Sep 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
lib/*
node_modules/*
vendor/*
9 changes: 8 additions & 1 deletion lib/install/config/webpacker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ development:
<<: *default
compile: true

# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
host: localhost
port: 3035
public: localhost:3035
hmr: false
https: false
# Inline should be set to true if using HMR
inline: true
overlay: true
disable_host_check: true
use_local_ip: false

test:
<<: *default
Expand Down
18 changes: 14 additions & 4 deletions lib/webpacker/dev_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ def running?
end

def hot_module_replacing?
fetch(:hmr)
case fetch(:hmr)
when true, "true"
true
else
false
end
end

def host
Expand All @@ -29,20 +34,25 @@ def port
end

def https?
fetch(:https)
case fetch(:https)
when true, "true"
true
else
false
end
end

def protocol
https? ? "https" : "http"
end

def host_with_port
"#{host}:#{port}"
fetch(:public)
end

private
def fetch(key)
config.dev_server.fetch(key, defaults[key])
ENV["WEBPACKER_DEV_SERVER_#{key.upcase}"] || config.dev_server.fetch(key, defaults[key])
end

def defaults
Expand Down
37 changes: 8 additions & 29 deletions lib/webpacker/dev_server_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,12 @@ def run
end

private

def load_config
@config_file = File.join(@app_path, "config/webpacker.yml")
@default_listen_host_addr = ENV["NODE_ENV"] == "development" ? "localhost" : "0.0.0.0"

dev_server = YAML.load_file(@config_file)[ENV["RAILS_ENV"]]["dev_server"]

@hostname = args("--host") || dev_server["host"]
@port = args("--port") || dev_server["port"]
@https = @argv.include?("--https") || dev_server["https"]
@dev_server_addr = "http#{"s" if @https}://#{@hostname}:#{@port}"
@listen_host_addr = args("--listen-host") || @default_listen_host_addr
@hostname = dev_server["host"]
@port = dev_server["port"]

rescue Errno::ENOENT, NoMethodError
$stdout.puts "Webpack dev_server configuration not found in #{@config_file}."
Expand All @@ -32,7 +26,7 @@ def load_config
end

def detect_port!
server = TCPServer.new(@listen_host_addr, @port)
server = TCPServer.new(@hostname, @port)
server.close

rescue Errno::EADDRINUSE
Expand All @@ -41,32 +35,17 @@ def detect_port!
end

def execute_cmd
argv = @argv.dup

# Delete supplied host, port and listen-host CLI arguments
["--host", "--port", "--listen-host"].each do |arg|
argv.delete(args(arg))
argv.delete(arg)
end

env = { "NODE_PATH" => @node_modules_path.shellescape }

cmd = [
"#{@node_modules_path}/.bin/webpack-dev-server", "--progress", "--color",
"--config", @webpack_config,
"--host", @listen_host_addr,
"--public", "#{@hostname}:#{@port}",
"--port", @port.to_s
] + argv
"#{@node_modules_path}/.bin/webpack-dev-server",
"--progress",
"--color",
"--config", @webpack_config
]

Dir.chdir(@app_path) do
exec env, *cmd
end
end

def args(key)
index = @argv.index(key)
index ? @argv[index + 1] : nil
end
end
end
21 changes: 19 additions & 2 deletions package/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@ const { safeLoad } = require('js-yaml')
const { readFileSync } = require('fs')

const filePath = resolve('config', 'webpacker.yml')
const config = safeLoad(readFileSync(filePath), 'utf8')
const config = safeLoad(readFileSync(filePath), 'utf8')[process.env.NODE_ENV]

module.exports = config[process.env.NODE_ENV]
const isBoolean = str => /^true/.test(str) || /^false/.test(str)

const fetch = key =>
(isBoolean(process.env[key]) ? JSON.parse(process.env[key]) : process.env[key])

const devServer = (key) => {
const envValue = fetch(`WEBPACKER_DEV_SERVER_${key.toUpperCase().replace(/_/g, '')}`)
if (typeof envValue === 'undefined' || envValue === null) return config.dev_server[key]
return envValue
}

if (config.dev_server) {
Object.keys(config.dev_server).forEach((key) => {
config.dev_server[key] = devServer(key)
})
}

module.exports = config
6 changes: 3 additions & 3 deletions package/environment.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/* eslint global-require: 0 */
/* eslint import/no-dynamic-require: 0 */

const config = require('./config')
const assetHost = require('./asset_host')

const { basename, dirname, join, relative, resolve } = require('path')
const { sync } = require('glob')
const extname = require('path-complete-extname')
Expand All @@ -12,6 +9,9 @@ const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const ManifestPlugin = require('webpack-manifest-plugin')

const config = require('./config')
const assetHost = require('./asset_host')

function getLoaderMap() {
const result = new Map()
const paths = sync(resolve(__dirname, 'loaders', '*.js'))
Expand Down
26 changes: 15 additions & 11 deletions package/environments/development.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
const webpack = require('webpack')
const Environment = require('../environment')
const { dev_server } = require('../config')
const { dev_server: devServer } = require('../config')
const assetHost = require('../asset_host')
const webpack = require('webpack')

module.exports = class extends Environment {
constructor() {
super()

if (dev_server.hmr) {
if (devServer.hmr) {
this.plugins.set('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
this.plugins.set('NamedModules', new webpack.NamedModulesPlugin())
}
}

toWebpackConfig() {
const result = super.toWebpackConfig()
if (dev_server.hmr) {
if (devServer.hmr) {
result.output.filename = '[name]-[hash].js'
}
result.output.pathinfo = true
result.devtool = 'cheap-eval-source-map'
result.devServer = {
host: dev_server.host,
port: dev_server.port,
https: dev_server.https,
hot: dev_server.hmr,
contentBase: assetHost.path,
publicPath: assetHost.publicPath,
clientLogLevel: 'none',
compress: true,
disableHostCheck: devServer.disable_host_check,
host: devServer.host,
port: devServer.port,
https: devServer.https,
hot: devServer.hmr,
contentBase: assetHost.path,
inline: devServer.inline,
useLocalIp: devServer.use_local_ip,
public: devServer.public,
publicPath: assetHost.publicPath,
historyApiFallback: true,
headers: {
'Access-Control-Allow-Origin': '*'
},
overlay: true,
overlay: devServer.overlay,
watchOptions: {
ignored: /node_modules/
},
Expand Down
2 changes: 1 addition & 1 deletion package/environments/production.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const Environment = require('../environment')
const webpack = require('webpack')
const CompressionPlugin = require('compression-webpack-plugin')
const Environment = require('../environment')

module.exports = class extends Environment {
constructor() {
Expand Down
2 changes: 1 addition & 1 deletion package/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* eslint global-require: 0 */
/* eslint import/no-dynamic-require: 0 */

const Environment = require('./environment')
const { resolve } = require('path')
const { existsSync } = require('fs')
const Environment = require('./environment')

function createEnvironment() {
const path = resolve(__dirname, 'environments', `${process.env.NODE_ENV}.js`)
Expand Down
6 changes: 3 additions & 3 deletions package/loaders/file.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const config = require('../config')
const assetHost = require('../asset_host')
const { join } = require('path')
const { source_path } = require('../config')
const assetHost = require('../asset_host')

module.exports = {
test: /\.(jpg|jpeg|png|gif|svg|eot|otf|ttf|woff|woff2)$/i,
use: [{
loader: 'file-loader',
options: {
name: '[path][name]-[hash].[ext]',
context: join(config.source_path),
context: join(source_path),
publicPath: assetHost.publicPathWithHost
}
}]
Expand Down
4 changes: 2 additions & 2 deletions package/loaders/style.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const path = require('path')
const config = require('../config')
const { dev_server: devServer } = require('../config')

const postcssConfigPath = path.resolve(process.cwd(), '.postcssrc.yml')
const isProduction = process.env.NODE_ENV === 'production'
const extractCSS = !(config.dev_server && config.dev_server.hmr)
const extractCSS = !(devServer && devServer.hmr)

const extractOptions = {
fallback: 'style-loader',
Expand Down
4 changes: 2 additions & 2 deletions package/loaders/vue.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const config = require('../config')
const { dev_server: devServer } = require('../config')

const isProduction = process.env.NODE_ENV === 'production'
const extractCSS = !(config.dev_server && config.dev_server.hmr)
const extractCSS = !(devServer && devServer.hmr)

module.exports = {
test: /\.vue(\.erb)?$/,
Expand Down