diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..d3266ca7c --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +lib/* +node_modules/* +vendor/* diff --git a/lib/install/config/webpacker.yml b/lib/install/config/webpacker.yml index e62a7acd1..1d0263e0e 100644 --- a/lib/install/config/webpacker.yml +++ b/lib/install/config/webpacker.yml @@ -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 diff --git a/lib/webpacker/dev_server.rb b/lib/webpacker/dev_server.rb index cd47e061b..0492cae53 100644 --- a/lib/webpacker/dev_server.rb +++ b/lib/webpacker/dev_server.rb @@ -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 @@ -29,7 +34,12 @@ def port end def https? - fetch(:https) + case fetch(:https) + when true, "true" + true + else + false + end end def protocol @@ -37,12 +47,12 @@ def protocol 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 diff --git a/lib/webpacker/dev_server_runner.rb b/lib/webpacker/dev_server_runner.rb index 6792f1b34..e893f578f 100644 --- a/lib/webpacker/dev_server_runner.rb +++ b/lib/webpacker/dev_server_runner.rb @@ -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}." @@ -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 @@ -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 diff --git a/package/config.js b/package/config.js index dd9e3de7c..bac05690f 100644 --- a/package/config.js +++ b/package/config.js @@ -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 diff --git a/package/environment.js b/package/environment.js index 1a0dbe2a5..b8c7ca9be 100644 --- a/package/environment.js +++ b/package/environment.js @@ -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') @@ -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')) diff --git a/package/environments/development.js b/package/environments/development.js index 72b007e41..ee5070a7d 100644 --- a/package/environments/development.js +++ b/package/environments/development.js @@ -1,13 +1,13 @@ +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()) } @@ -15,25 +15,29 @@ module.exports = class extends Environment { 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/ }, diff --git a/package/environments/production.js b/package/environments/production.js index 7f81c3a2a..53beda4af 100644 --- a/package/environments/production.js +++ b/package/environments/production.js @@ -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() { diff --git a/package/index.js b/package/index.js index 4e46b24b0..e8b54ff2f 100644 --- a/package/index.js +++ b/package/index.js @@ -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`) diff --git a/package/loaders/file.js b/package/loaders/file.js index f369d66c5..be491d640 100644 --- a/package/loaders/file.js +++ b/package/loaders/file.js @@ -1,6 +1,6 @@ -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, @@ -8,7 +8,7 @@ module.exports = { loader: 'file-loader', options: { name: '[path][name]-[hash].[ext]', - context: join(config.source_path), + context: join(source_path), publicPath: assetHost.publicPathWithHost } }] diff --git a/package/loaders/style.js b/package/loaders/style.js index 94ff46dd1..0b6abf324 100644 --- a/package/loaders/style.js +++ b/package/loaders/style.js @@ -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', diff --git a/package/loaders/vue.js b/package/loaders/vue.js index aadee25e3..2d5780320 100644 --- a/package/loaders/vue.js +++ b/package/loaders/vue.js @@ -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)?$/,