Skip to content

Commit

Permalink
feat: migrate from brickyard to be standalone package
Browse files Browse the repository at this point in the history
  • Loading branch information
e-cloud committed Jul 5, 2016
1 parent 632580f commit 5f4515e
Show file tree
Hide file tree
Showing 4 changed files with 490 additions and 8 deletions.
113 changes: 113 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* Created by scott on 16-3-31.
*/
'use strict'

const logger = require('log4js').getLogger('dev-command')
const configMaker = require('./webpack.config')
const webpack = require('webpack')
const WebpackDevServer = require('webpack-dev-server')
const util = require('util')
const proxy = require('http-proxy-middleware')
const morgan = require('morgan')
const _ = require("lodash")

module.exports = {
register,
run
}

/**
*
* @param {Command} cmd
* @param {function(Object)} runnerCallback
*/
function register(cmd, runnerCallback) {
logger.trace('register dev command')

cmd
.description('develop a program')
.arguments('<program...>')
.usage('<program...> [options]')
.option('--https', 'use https protocol to serve the resources')
.option('--port <port>', 'access port', parseInt)
.option('--proxy-port <port>', 'access proxy port', parseInt)
.option('--livereload', 'livereload')
.option('--dest <dir>', 'output dir')
.option('--watch', 'watch file for changes')
.option('--lint', 'lint the files')
.option('--no-browse', 'open the browser automatically')
.option('--no-daemon', 'no background serve')
.option('--show-config', 'output the webpack config')
.action(function (program) {
logger.trace('dev command invoke')

const option = Object.assign({ program: program }, this.opts())

option.bsProxy = {
port: option.proxyPort,
host: option.proxyHost
}

delete option.proxyPort
delete option.proxyHost

runnerCallback && runnerCallback(option)
})

return cmd
}

function run(runtime) {
logger.trace('dev command running')

// 无插件退出
if (_.isEmpty(runtime.plugins)) {
process.exit(1)
}

const webpackConfig = configMaker.make(runtime)
if (runtime.config.showConfig) {
console.log(util.inspect(webpackConfig, { depth: 4 }))
} else {
const compiler = webpack(webpackConfig)

const server = new WebpackDevServer(compiler, {
// Tell the webpack dev server from where to find the files to serve.
contentBase: webpackConfig.output.path,
colors: true,
publicPath: webpackConfig.output.publicPath,
host: runtime.config.host,
port: runtime.config.port,
hot: true,
https: runtime.config.https,
stats: {
assets: true,
colors: true,
version: true,
hash: true,
timings: true,
chunks: false
}
})

server.use(morgan('dev'))


// use the express server from webpack-dev-server
// todo: when upgrade webpack and webpack-dev-server, this may needs to be reviewed
if (runtime.config.apiProxy) {
server.use(proxy(runtime.config.apiProxy.address, {
target: runtime.config.apiProxy.host,
ws: true,
changeOrigin: true,
secure: false
}))
}


server.listen(runtime.config.port, runtime.config.host, function () {
logger.info('webpack-dev-server running...')
})
}
}
53 changes: 45 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,49 @@
{
"name": "package",
"author": "John Doe",
"version": "0.0.0",
"description": "nothing.",
"name": "brickyard-command-dev",
"version": "0.0.2",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "e-cloud",
"license": "ISC",
"dependencies": {
"autoprefixer": "latest",
"anybar-webpack": "^1.2.0",
"babel-core": "^6.4.0",
"babel-loader": "^6.2.1",
"babel-plugin-transform-runtime": "^6.4.3",
"babel-polyfill": "^6.3.14",
"babel-preset-es2015": "^6.3.13",
"babel-preset-stage-0": "^6.3.13",
"babel-runtime": "^6.3.19",
"browser-sync": "^2.11.1",
"browser-sync-webpack-plugin": "^1.0.1",
"css-loader": "^0.23.1",
"expose-loader": "^0.7.0",
"file-loader": "^0.8.5",
"glob": "^7.0.3",
"html-loader": "^0.4.3",
"html-webpack-plugin": "^2.0.0",
"http-proxy-middleware": "^0.14.0",
"imports-loader": "^0.6.5",
"lodash": "^4.6.1",
"log4js": "^0.6.33",
"morgan": "^1.7.0",
"ng-annotate": "^1.2.1",
"ng-annotate-loader": "~0.1.0",
"ngtemplate-loader": "^1.3.1",
"node-sass": "^3.4.2",
"postcss-loader": "^0.8.2",
"postcss-normalize-charset": "latest",
"progress-bar-webpack-plugin": "^1.8.0",
"resolve-url-loader": "^1.4.3",
"sass-loader": "^3.2.0",
"style-loader": "^0.13.0",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"
},
"devDependencies": {
"conventional-changelog": "^1.1.0",
"eslint": "^2.8.0",
Expand All @@ -11,10 +52,6 @@
"ghooks": "^1.2.1",
"validate-commit-msg": "^2.6.1"
},
"scripts": {
"test": "echo 'no test!'"
},
"license": "ISC",
"config": {
"validate-commit-msg": {
"types": [
Expand Down
194 changes: 194 additions & 0 deletions webpack.config.default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/**
* Created by scott on 16-5-6.
*/

'use strict'

const path = require('path')
const _ = require('lodash')
const webpack = require('webpack')
const autoPrefixer = require('autoprefixer')
const glob = require('glob')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')

const butil = require('../../util')

module.exports = {
make: function (runtime, configFactory) {
const runtimeConfig = runtime.config

const defaultConfig = constructDefault(runtimeConfig)

const targetConfig = configFactory(runtimeConfig, defaultConfig)

targetConfig.plugins.push(defineGlobals(runtimeConfig, targetConfig.debug))

const htmlEntries = createEntries(runtime.plugins)

targetConfig.plugins.push.apply(targetConfig.plugins, htmlEntries)

const pluginAliases = aliasPlugins(runtime.plugins)

const pluginsConfig = mergePluginWebpackConfig(runtime.plugins)

Array.prototype.push.apply(targetConfig.entry.main, Object.keys(runtime.plugins))

return _.mergeWith(targetConfig, pluginsConfig, defaultConfig, { resolve: { alias: pluginAliases } }, mergeOperator)
}
}

/**
* construct the most common webpack config,
* which can be used in dev mode and release mode
*
* @param config
* @returns Object
*/
function constructDefault(config) {
return {
context: path.resolve(process.cwd(), config.pluginStore),
output: {
path: path.join(config.outputBase, 'www')
},
module: {
loaders: [
//**********************************
// special
//**********************************
{
test: /jquery$/,
loader: 'expose?$!expose?jQuery'
},
{
test: /index\.html$/,
loader: 'html?attrs=link:href img:src use:xlink:href'
}
]
},
plugins: [
new webpack.optimize.DedupePlugin(),
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
'window.jQuery': 'jquery'
}),
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin('.bower.json', ['main'])
),
//new ProgressBarPlugin()
],
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.js'],
root: [path.resolve(process.cwd(), 'node_modules'), path.join(config.outputBase, 'bower_components')]
},
postcss: function () {
return [
autoPrefixer({
browsers: [
'last 2 versions',
'> 1%',
'not ie <= 8'
],
add: true
}),
require('postcss-normalize-charset')
]
}
}
}

// ==========================================================

/**
* retrieve webpack config of each plugins,
* and merge them into one config object
* @param plugins
*/
function mergePluginWebpackConfig(plugins) {
const pattern = butil.getFileGlobPattern('', _.map(plugins, 'raw.path'), 'webpack.config.js')

return _.mergeWith.apply(_,
_.chain(glob.sync(pattern))
.map(function (_path) {
return require(_path)
})
.value()
.concat([mergeOperator])
)
}

/**
* an operator to merge array
*
* @param objValue
* @param srcValue
* @returns {Array|Array.<T>|string|*|Buffer}
*/
function mergeOperator(objValue, srcValue) {
if (Array.isArray(objValue)) {
return objValue.concat(srcValue)
}
}

/**
* create html entries based on each plugin's declaration
* @param plugins
* @returns {*}
*/
function createEntries(plugins) {
return _.chain(plugins)
.map(function (plugin) {
let entry = _.get(plugin, 'raw.plugin.entry')
if (Array.isArray(entry)) {
return entry.reduce(function (result, value) {
result.push(createEntry(path.join(plugin.path, value)))
}, [])
} else if (entry) {
return [createEntry(path.join(plugin.path, entry))]
} else {
return null
}
})
.flatten()
.compact()
.value()
}

/**
* create the html entry file with target template file, using HtmlWebpackPlugin
* @param _path
*/
function createEntry(_path) {
return new HtmlWebpackPlugin({
filename: 'index.html',
template: _path
})
}

/**
* create shimming for plugins, then webpack can resolve the plugin correctly
* @param plugins
* @returns {*}
*/
function aliasPlugins(plugins) {
return _.reduce(plugins, function (result, plugin) {
result[plugin.name] = plugin.path
return result
}, {})
}

/**
* define globals variables for injecting them into source scope
* @param runtimeConfig
* @param isDebug
* @returns {webpack.DefinePlugin}
*/
function defineGlobals(runtimeConfig, isDebug) {
const globals = Object.assign({
APP_DEBUG_MODE: isDebug || runtimeConfig.debuggable
}, runtimeConfig.globals)

return new webpack.DefinePlugin(globals)
}

0 comments on commit 5f4515e

Please sign in to comment.