-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: migrate from brickyard to be standalone package
- Loading branch information
Showing
4 changed files
with
490 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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...') | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
|
Oops, something went wrong.