UNPKG

makestatic-pack-webpack

Version:

Bundle assets using webpack

202 lines (174 loc) 4.95 kB
const path = require('path') const entry = './js/index.js' const shortcuts = ['script', 'markup', 'styles'] const standardKeys = [ 'url', 'input', 'output', 'ignore', 'matchers', 'lifecycle', 'server', 'static', 'test', 'manifest', 'gzip', 'deploy', 'clean', 'provider' ].concat(shortcuts) /** * Converts the build configuration into a webpack compatible configuration * removing fields that are not used by webpack. * * @class Config */ class Config { /** * Creates a Config. * * @constructor Config * @param {Object} context the processing context. */ constructor (context) { this.context = context } /** * Get a webpack compatible configuration. * * @function getConfig * @member Config * @param {Object} system plugins required by the system. * @param {Object} options plugin options. */ getConfig (system = {}, options = {}) { const log = this.context.log const opts = this.context.options const plugins = system.plugins // complex instances are mangled in the merge delete system.plugins shortcuts.forEach((k) => { if (typeof opts[k] === 'function') { opts[k] = opts[k](this.context) } }) let conf = Object.assign({}, this.context.config.raw) this.removeKeys(conf, standardKeys) const test = options.test || conf.test || require('./test') conf.plugins = conf.plugins || [] // plugins passed in the system take precedence // options specific to the plugin configuration are added afterwards conf.plugins = plugins.concat(conf.plugins) if (!conf.entry) { conf.entry = { 'js/main.js': [entry] } } conf.context = this.context.options.root conf.output = { path: opts.output, filename: '[name]' } //console.dir(opts.output) //process.exit(1) if (this.context.options.watch) { const BrowserSyncPlugin = require('browser-sync-webpack-plugin') const bsopts = this.context.options.server bsopts.server = bsopts.server || {} bsopts.server.baseDir = [this.context.options.output] const sync = this.context.options.sync /* istanbul ignore next: not going to mock snippet request */ bsopts.snippetOptions = { rule: { match: /<\/body>/i, fn: (snippet, match) => { // NOTE: when sync is false we disable injecting the browsersync // NOTE: snippet which means that browsersync is just a static // NOTE: file server if (sync === false) { return match } // browsersync uses document.write() which messes with CSP // so let's just used a plain script otherwise we // need to add `script-src 'unsafe-inline'` which is not cool const version = require('browser-sync/package.json').version const script = `<script defer ` + `src="/browser-sync/browser-sync-client.js?v=${version}"></script>` return script + match } } } const bs = new BrowserSyncPlugin( bsopts, { callback: (_, bs) => { // don't know a better way to get actual port in use yet const port = bs.server._connectionKey.replace(/^[^:]+:+/, '') log.info( `External IP: http://${bs.utils.devIp[0]}:${port}`) }} ) conf.plugins.push(bs) } conf.module = options.module || conf.module || { rules: [ { test: test.vendor, use: [ { loader: 'source-loader' } ] }, { test: test.css, use: [ { loader: 'source-loader' }, { loader: 'postcss-loader', options: opts.styles } ] }, { test: test.js, use: [ { loader: 'babel-loader', options: opts.script } ] }, { test: test.html, use: [ { loader: 'source-loader' }, { loader: 'reshape-loader', options: opts.markup } ] }, { test: /\.json$/, use: [ { loader: 'source-loader' } ] }, { test: test.static, loader: 'source-loader' } ] } conf.resolve = options.resolve || conf.resolve || { extensions: ['.js', '.jsx'], descriptionFiles: [] } conf.resolveLoader = options.resolveLoader || conf.resolveLoader || { modules: [ path.join(process.cwd(), 'node_modules') // NOTE: this slows things down dramatically // path.join(__dirname, 'node_modules') ] } return conf } /** * Remove keys from an object. */ removeKeys (conf, keys) { keys.forEach((k) => { delete conf[k] }) return conf } } module.exports = Config