Skip to content

Commit

Permalink
Allow dev server settings to be overriden by env variables
Browse files Browse the repository at this point in the history
  • Loading branch information
gauravtiwari committed Sep 24, 2017
1 parent 8f48616 commit 7bd2c93
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 59 deletions.
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

0 comments on commit 7bd2c93

Please sign in to comment.