Skip to content

Commit

Permalink
Consitently use NODE_ENV and restructure npm package for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
gauravtiwari committed Feb 27, 2018
1 parent f01102a commit 0d08ab4
Show file tree
Hide file tree
Showing 30 changed files with 393 additions and 167 deletions.
1 change: 1 addition & 0 deletions lib/webpacker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def instance
end

require "webpacker/instance"
require "webpacker/env"
require "webpacker/configuration"
require "webpacker/manifest"
require "webpacker/compiler"
Expand Down
2 changes: 1 addition & 1 deletion lib/webpacker/dev_server_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def run
private
def load_config
@config_file = File.join(@app_path, "config/webpacker.yml")
dev_server = YAML.load_file(@config_file)[ENV["RAILS_ENV"]]["dev_server"]
dev_server = YAML.load_file(@config_file)[ENV["NODE_ENV"]]["dev_server"]

@hostname = dev_server["host"]
@port = dev_server["port"]
Expand Down
46 changes: 46 additions & 0 deletions lib/webpacker/env.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class Webpacker::Env
DEFAULT = "production".freeze

delegate :config_path, :logger, to: :@webpacker

def self.inquire(webpacker)
new(webpacker).inquire
end

def initialize(webpacker)
@webpacker = webpacker
end

def inquire
fallback_env_warning unless current
(current || DEFAULT).inquiry
end

private
def current
node_env.presence_in(available_environments)
end

def fallback_env_warning
logger.info "#{node_env} environment is not defined in config/webpacker.yml, falling back to #{DEFAULT} environment"
end

def available_environments
if config_path.exist?
YAML.load(config_path.read).keys
else
[].freeze
end
rescue Psych::SyntaxError => e
raise "YAML syntax error occurred while parsing #{config_path}. " \
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
"Error: #{e.message}"
end

def node_env
ENV.fetch("NODE_ENV")
rescue KeyError
raise "Using webpacker requires that you set NODE_ENV environment variables. " \
"Valid values are #{available_environments.join(', ')}"
end
end
13 changes: 1 addition & 12 deletions lib/webpacker/instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ def initialize(root_path: Rails.root, config_path: Rails.root.join("config/webpa
end

def env
(ENV["NODE_ENV"].presence_in(available_environments) ||
Rails.env.presence_in(available_environments) ||
"production".freeze).inquiry
@env ||= Webpacker::Env.inquire self
end

def config
Expand All @@ -32,13 +30,4 @@ def manifest
def commands
@commands ||= Webpacker::Commands.new self
end

private
def available_environments
if config_path.exist?
YAML.load(config_path.read).keys
else
[].freeze
end
end
end
6 changes: 3 additions & 3 deletions package/__tests__/config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* global test expect, describe */

const chdirApp = () => process.chdir('test/test_app')
const chdirCwd = () => process.chdir(process.cwd())
chdirApp()
const { chdirTestApp, chdirCwd } = require('../utils/helpers')

chdirTestApp()

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

Expand Down
31 changes: 31 additions & 0 deletions package/__tests__/dev_server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* global test expect, describe */

const { chdirTestApp, chdirCwd } = require('../utils/helpers')

chdirTestApp()

describe('DevServer', () => {
beforeEach(() => jest.resetModules())
afterAll(chdirCwd)

test('with development environment', () => {
process.env.NODE_ENV = 'development'
process.env.WEBPACKER_DEV_SERVER_HOST = '0.0.0.0'
process.env.WEBPACKER_DEV_SERVER_PORT = 5000

const devServer = require('../dev_server')
expect(devServer).toBeDefined()
expect(devServer.host).toEqual('0.0.0.0')
expect(devServer.port).toEqual('5000')
})

test('with undefined environment', () => {
delete process.env.NODE_ENV
expect(() => require('../dev_server')).toThrow()
})

test('with production environment', () => {
process.env.NODE_ENV = 'production'
expect(require('../dev_server')).toEqual({})
})
})
28 changes: 28 additions & 0 deletions package/__tests__/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* global test expect, describe */

const { chdirTestApp, chdirCwd } = require('../utils/helpers')

chdirTestApp()

const error = `Using 'webpacker' requires that you specify 'NODE_ENV' environment variables.
Valid values are default|development|test|production. Instead, received: undefined`

describe('Env', () => {
beforeEach(() => jest.resetModules())
afterAll(chdirCwd)

test('returns set node environment', () => {
process.env.NODE_ENV = 'development'
expect(require('../env')).toEqual('development')
})

test('with no NODE_ENV throws an error', () => {
delete process.env.NODE_ENV
expect(() => require('../env')).toThrowError(error)
})

test('with non-standard environment', () => {
process.env.NODE_ENV = 'foo'
expect(require('../env')).toEqual('production')
})
})
35 changes: 35 additions & 0 deletions package/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* global test expect, describe */

const { chdirTestApp, chdirCwd } = require('../utils/helpers')

chdirTestApp()

describe('Webpack config', () => {
beforeEach(() => jest.resetModules())
afterAll(chdirCwd)

test('returns a development config', () => {
process.env.NODE_ENV = 'development'
const { environment } = require('../index')
expect(environment.toWebpackConfig()).toMatchObject({
devServer: {
host: 'localhost',
port: 3035
}
})
})

test('with no NODE_ENV throws an error', () => {
delete process.env.NODE_ENV
expect(() => require('../index')).toThrow()
})

test('returns a production config for non-standard env', () => {
process.env.NODE_ENV = 'staging'
const { environment } = require('../index')
expect(environment.toWebpackConfig()).toMatchObject({
devtool: 'nosources-source-map',
stats: 'normal'
})
})
})
44 changes: 14 additions & 30 deletions package/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,25 @@ const { safeLoad } = require('js-yaml')
const { readFileSync } = require('fs')
const deepMerge = require('./utils/deep_merge')
const { isArray } = require('./utils/helpers')
const env = require('./env')

const defaultFilePath = require.resolve('../lib/install/config/webpacker.yml')
const filePath = resolve('config', 'webpacker.yml')
const defaultConfigPath = require.resolve('../lib/install/config/webpacker.yml')
const configPath = resolve('config', 'webpacker.yml')

const environment = process.env.NODE_ENV || 'development'
const defaultConfig = safeLoad(readFileSync(defaultFilePath), 'utf8')[environment]
const appConfig = safeLoad(readFileSync(filePath), 'utf8')[environment]
const getConfig = () => {
const defaults = safeLoad(readFileSync(defaultConfigPath), 'utf8')[env]
const app = safeLoad(readFileSync(configPath), 'utf8')[env]

if (isArray(appConfig.extensions) && appConfig.extensions.length) {
delete defaultConfig.extensions
} else {
/* eslint no-console: 0 */
console.warn('No extensions specified in webpacker.yml, using default extensions\n')
}

const config = deepMerge(defaultConfig, appConfig)
if (isArray(app.extensions) && app.extensions.length) {
delete defaults.extensions
}

const isBoolean = str => /^true/.test(str) || /^false/.test(str)
const config = deepMerge(defaults, app)

const fetch = key =>
(isBoolean(process.env[key]) ? JSON.parse(process.env[key]) : process.env[key])
config.outputPath = resolve('public', config.public_output_path)
config.publicPath = `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1')

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
return config
}

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

config.outputPath = resolve('public', config.public_output_path)
config.publicPath = `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1')

module.exports = config
module.exports = getConfig()
5 changes: 0 additions & 5 deletions package/config_types/__tests__/config_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ test('new', () => {
expect(list).toBeInstanceOf(Array)
})

test('set', () => {
const list = new ConfigList()
expect(list.set('key', 'value')).toEqual([{ key: 'key', value: 'value' }])
})

test('get', () => {
const list = new ConfigList()
list.append('key', 'value')
Expand Down
9 changes: 0 additions & 9 deletions package/config_types/config_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ class ConfigList extends Array {
return this[index].value
}

/**
* @deprecated after the 3.0.2 release and will be removed in the next major release
*/
set(key, value) {
/* eslint no-console: 0 */
console.warn('set is deprecated! Use append instead')
return this.append(key, value)
}

append(key, value) {
return this.add({ key, value })
}
Expand Down
23 changes: 23 additions & 0 deletions package/dev_server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { isBoolean, isEmpty } = require('./utils/helpers')
const config = require('./config')

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

const devServer = () => {
const devServerConfig = config.dev_server

if (devServerConfig) {
Object.keys(devServerConfig).forEach((key) => {
const envValue = fetch(`WEBPACKER_DEV_SERVER_${key.toUpperCase().replace(/_/g, '')}`)
if (isEmpty(envValue)) return devServerConfig[key]
devServerConfig[key] = envValue
})
}

return devServerConfig || {}
}

module.exports = devServer()
27 changes: 27 additions & 0 deletions package/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const { resolve } = require('path')
const { safeLoad } = require('js-yaml')
const { readFileSync } = require('fs')

const configPath = resolve('config', 'webpacker.yml')
const DEFAULT_ENV = 'production'

const env = () => {
const nodeEnv = process.env.NODE_ENV
const config = safeLoad(readFileSync(configPath), 'utf8')
const availableEnvironments = Object.keys(config).join('|')

if (!nodeEnv) {
throw new Error(`
Using 'webpacker' requires that you specify 'NODE_ENV' environment variables.
Valid values are ${availableEnvironments}. Instead, received: ${nodeEnv}`)
}

const regex = new RegExp(availableEnvironments, 'g')
if (nodeEnv.match(regex)) return nodeEnv

/* eslint no-console: 0 */
console.warn(`${nodeEnv} environment is not defined in config/webpacker.yml, falling back to ${DEFAULT_ENV}`)
return DEFAULT_ENV
}

module.exports = env()
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
// environment.js expects to find config/webpacker.yml and resolved modules from
// the root of a Rails project

const chdirApp = () => process.chdir('test/test_app')
const chdirCwd = () => process.chdir(process.cwd())
chdirApp()
const { chdirTestApp, chdirCwd } = require('../../utils/helpers')

chdirTestApp()

const { resolve } = require('path')
const rules = require('../rules')
const { ConfigList } = require('../config_types')
const Environment = require('../environment')
const rules = require('../../rules')
const { ConfigList } = require('../../config_types')
const Environment = require('../base')

describe('Environment', () => {
afterAll(chdirCwd)
Expand Down
8 changes: 4 additions & 4 deletions package/environment.js → package/environments/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin')
const ManifestPlugin = require('webpack-manifest-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')

const { ConfigList, ConfigObject } = require('./config_types')
const rules = require('./rules')
const config = require('./config')
const { ConfigList, ConfigObject } = require('../config_types')
const rules = require('../rules')
const config = require('../config')

const getLoaderList = () => {
const result = new ConfigList()
Expand Down Expand Up @@ -85,7 +85,7 @@ const getBaseConfig = () =>
}
})

module.exports = class Environment {
module.exports = class Base {
constructor() {
this.loaders = getLoaderList()
this.plugins = getPluginList()
Expand Down
7 changes: 4 additions & 3 deletions package/environments/development.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const webpack = require('webpack')
const Environment = require('../environment')
const { dev_server: devServer, outputPath: contentBase, publicPath } = require('../config')
const Base = require('./base')
const devServer = require('../dev_server')
const { outputPath: contentBase, publicPath } = require('../config')

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

Expand Down
Loading

0 comments on commit 0d08ab4

Please sign in to comment.