Skip to content

Instantly share code, notes, and snippets.

@libetl
Last active June 9, 2017 00:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save libetl/79023dec57e4f4a02b48ee05b8d34d68 to your computer and use it in GitHub Desktop.
Save libetl/79023dec57e4f4a02b48ee05b8d34d68 to your computer and use it in GitHub Desktop.
webpack2
/* imports */
const webpack = require('webpack')
const path = require('path')
const fs = require('fs')
const unzip = require('unzip2')/* imports */
const webpack = require('webpack')
const path = require('path')
const fs = require('fs')
const unzip = require('unzip2')
const mkdirp = require('mkdirp')
const glob = require('glob')
const WebpackBeforeBuildPlugin = require('before-build-webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const PropertiesReader = require('properties-reader')
const noOp = require('noop-webpack-plugin')
const rawNcp = require('ncp').ncp
const ncp = (source, target) => { // hack on ncp to support Promises (recursive copy)
return new Promise((resolve) => {
rawNcp(source, target, resolve)
})
}
/* definitions */
const customMessages = './src/main/resources/checkout-messages/'
const srcAssets = './src/main/webapp/assets/'
const webpackFolder = './target/webpack/'
const webpackAssetsFolder = `${webpackFolder}assets/`
const target = path.join(__dirname, 'target/classes/')
const targetAssets = `${target}assets/`
const m2repository = (!process.env.M2_REPOSITORY || process.env.M2_REPOSITORY === 'null') ? `${process.env.HOME || process.env.HOMEPATH}/.m2/repository/` : process.env.M2_REPOSITORY
const homegrownVersion = process.env.HOMEGROWN_VERSION || '6.5.0'
const listOfHandlebarsTemplates = {ALL_TEMPLATES: ''} //will be populated later on
/* resources */
const openSourceLibs = ['babel-polyfill', 'imports-loader?this=>window!jquery', 'modernizr', 'underscore', 'backbone', 'google-libphonenumber',
'intl-tel-input', `${webpackAssetsFolder}js/libs/polyfills/placeholders.js`, 'moment', 'exports-loader?I18n=this!i18n-js']
const bootstrap = `${webpackAssetsFolder}js/webpack-bootstrap.js`
const homegrownLibFiles = [`exports-loader?s_exp=AppMeasurement!${webpackAssetsFolder}js/libs/s_code.js`,
`${webpackAssetsFolder}js/homegrown.js`,
...['homegrown-plugin-utility', 'autocomplete', 'alert', 'analytics', 'character-count', 'content-slider',
'date', 'dates-and-currency', 'interstitial', 'toggle', 'tooltip', 'homegrown-modernizr-tests'].map(
lib => `${webpackAssetsFolder}js/libs/${lib}.js`),
`${webpackAssetsFolder}js/models/arrangee.js`,
`${webpackAssetsFolder}js/models/global-context.js`,
`${webpackAssetsFolder}js/presenters/site-presenter.js`]
const allHandlebarsFiles = () => [`${webpackAssetsFolder}js/libs/handlebars.helpers.js`, ...glob.sync(`${webpackAssetsFolder}views/**/*.hbs`)]
const javascriptFiles = glob.sync(`${srcAssets}js/**/*.js`).filter(asset => !asset.includes('webpack-boostrap') && !asset.includes('libs'))
.map(asset => asset.replace(srcAssets, webpackAssetsFolder))
/* plugins */
const beforeBuild = new WebpackBeforeBuildPlugin((compiler, callback) => {
const unpackhomegrownAssets = (entry) => {
if (['.hbs', '.svg', '.png', '.gif', '.ttf', '.woff', '.eot'].includes(entry.path.substring(entry.path.lastIndexOf('.')))) {
mkdirp.sync(`${webpackFolder}${entry.path.substring(0, entry.path.lastIndexOf('/'))}`)
entry.pipe(fs.createWriteStream(`${webpackFolder}${entry.path}`))
} else if (entry.path.endsWith('.less')) {
mkdirp.sync(`${webpackFolder}${entry.path.replace('less/', '').substring(0, entry.path.lastIndexOf('/'))}`)
entry.pipe(fs.createWriteStream(`${webpackFolder}${entry.path.replace('less/', '')}`))
} else if (entry.path.match(/homegrown.*\.properties/)) {
entry.pipe(fs.createWriteStream(`${webpackFolder}/messages/${entry.path}`))
} else {
entry.autodrain()
}
}
const unpackhomegrownJavascriptFiles = (entry) => {
if (entry.path.endsWith('.js')) {
mkdirp.sync(`${webpackFolder}${entry.path.substring(0, entry.path.lastIndexOf('/'))}`)
entry.pipe(fs.createWriteStream(`${webpackFolder}${entry.path}`))
} else {
entry.autodrain()
}
}
const mergeProperties = () => {
mkdirp.sync(`${webpackFolder}/merged-messages`)
glob.sync(`${webpackFolder}/messages/*.properties`).map((e) => e.substring(`${webpackFolder}/messages/homegrown`.length - 1).replace('.properties', '')).forEach((ext) => {
if (fs.existsSync(`${customMessages}/checkout${ext}.properties`)) {
fs.writeFileSync(`${webpackFolder}/merged-messages/messages${ext}.properties`,
Object.entries(PropertiesReader(`${webpackFolder}/messages/homegrown${ext}.properties`)
.append(`${customMessages}/checkout${ext}.properties`).getAllProperties())
.map((entry) => `${entry[0]}=${entry[1]}`).join('\n'), 'utf8')
} else {
fs.writeFileSync(`${webpackFolder}/merged-messages/messages${ext}.properties`,
Object.entries(PropertiesReader(`${webpackFolder}/messages/homegrown${ext}.properties`).getAllProperties())
.map((entry) => `${entry[0]}=${entry[1]}`).join('\n'), 'utf8')
}
})
}
const updateAllHandlebarsTemplates = () => listOfHandlebarsTemplates.ALL_TEMPLATES =
JSON.stringify(glob.sync(`${webpackAssetsFolder}views/**/*.hbs`).map(path => path.replace(`${webpackAssetsFolder}views/`, '')).map(path => path.replace('.hbs', '')))
const prepareWebpackTempFolder = () =>
ncp(`${srcAssets}views/`, `${webpackAssetsFolder}views/`).then(() =>
ncp(`${srcAssets}js`, `${webpackAssetsFolder}js`)).then(() =>
ncp(`${srcAssets}css/phones.css`, `${webpackAssetsFolder}css/phones.css`)).then(() =>
ncp(`${srcAssets}css/less/checkout.less`, `${webpackAssetsFolder}css/checkout.less`)).then(() =>
ncp(`${srcAssets}images/`, `${webpackAssetsFolder}images/`)).then(() =>
ncp(`${srcAssets}views/layouts/default.hbs`, `${webpackAssetsFolder}views/layouts/default.hbs`)).then(() =>
fs.createReadStream(`${m2repository}com/company/library/homegrown-core/${homegrownVersion}/homegrown-core-${homegrownVersion}.war`)
.pipe(unzip.Parse())
.on('entry', unpackhomegrownJavascriptFiles)
.on('close', () => {
mergeProperties()
updateAllHandlebarsTemplates()
callback()}))
mkdirp.sync(`${webpackFolder}/messages`)
fs.createReadStream(`${m2repository}com/company/library/homegrown-core/${homegrownVersion}/homegrown-core-${homegrownVersion}-classes.jar`)
.pipe(unzip.Parse())
.on('entry', unpackhomegrownAssets)
.on('close', prepareWebpackTempFolder)
})
const listAllHandlebarsFiles = new webpack.DefinePlugin(listOfHandlebarsTemplates)
const provideGlobalVariables = new webpack.ProvidePlugin({
$: 'jquery',
_: 'underscore',
jQuery: 'jquery',
Backbone: 'backbone',
moment: 'moment',
'window.jQuery': 'jquery',
Modernizr: 'modernizr',
Handlebars: 'handlebars/runtime',
I18n: 'i18n-js'
})
const extractCss = new ExtractTextPlugin({filename: `css/checkout-${process.env.VERSION}.css`})
const copyResults = new CopyWebpackPlugin(
[{from:`${webpackAssetsFolder}views`, to:`${targetAssets}views`, ignore : [ `layouts/default.hbs` ]},
{from:`${webpackAssetsFolder}images`, to:`${targetAssets}images`},
{from:`${webpackAssetsFolder}views/layouts/default.hbs`, to:`${targetAssets}views/layouts/default.hbs`,
transform: (content, path) => content.toString().replace(/-@project.version@/ig, `-${process.env.VERSION}`)},
{from:`${webpackFolder}merged-messages/`, to:`${target}`}])
const minify = process.env.NODE_ENV === 'dev' ? noOp() : new webpack.optimize.UglifyJsPlugin({minimize: true, comments: false})
/* configuration starts here */
module.exports = {
name: 'checkout-bundle',
target: 'web',
entry: () => {
return {
[`js/bundles/checkout-bundle-${process.env.VERSION}`]: [...openSourceLibs, bootstrap, ...homegrownLibFiles, ...javascriptFiles, ...allHandlebarsFiles()],
'js/css': [`${webpackAssetsFolder}css/checkout.less`,`${webpackAssetsFolder}css/phones.css`, `${webpackAssetsFolder}css/homegrown-core.less`],
}
},
output: {
path: targetAssets,
filename: '[name].js'
},
devtool: process.env.NODE_ENV === 'dev' ? 'source-map' : 'nosources-source-map',
module: {
rules: [
{
test: /\.modernizrrc?$/,
loader: "modernizr-loader!json-loader"
},
{
test: /\.hbs$/,
use: [{
loader: 'handlebars-loader',
options: {
knownHelpers: ['i18nMsg', 'block', 'include', 'includeJsBundle', 'eq', 'json', 'i18nJs', 'partial'],
partialDirs: [
path.join(__dirname, `${webpackAssetsFolder}views`)
],
rootRelatve: `${webpackAssetsFolder}views`
}
}],
},
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
presets: [['es2015', { loose: true, modules: false }]]
}
}]
},
{
test: /\.zip$/,
use: 'extract-loader'
},
{
test: /\.less$/,
use: extractCss.extract({
use: ['css-loader', 'less-loader']
})
},
{
test: /\.css$/,
use: extractCss.extract({
fallback: 'style-loader',
use: {
loader: 'css-loader',
options: {minimize: process.env.NODE_ENV !== 'dev'}
}
})
},
{
test: /\.(jpe?g|png|gif|svg|)$/i,
use: ['file-loader?name=../images/[name].[ext]']
},
{
test: /\.(eot|ttf|woff|woff2)$/i,
use: ['file-loader?name=../fonts/[name].[ext]']
}
]
},
resolve: {
alias: {
modernizr$: path.resolve(__dirname, ".modernizrrc")
}
},
plugins: [beforeBuild, listAllHandlebarsFiles, provideGlobalVariables, /* compile, */ extractCss, copyResults, minify]
}
process.env.NODE_ENV = process.env.NODE_ENV || 'prod'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment