Created
January 19, 2017 13:06
-
-
Save domjtalbot/1a003cb008fec25049706e795b543c06 to your computer and use it in GitHub Desktop.
Webpack build integrated with C# MVC.net - Useful for access to Webpack build hash for generating asset urls
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
<html xmlns="https://www.w3.org/1999/xhtml"> | |
<head> | |
@Html.Partial("_WebpackManifest") | |
</head> | |
<body class=""> | |
@Html.Partial("_WebpackScripts") | |
</body> | |
</html> |
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
@using Test.Models; | |
@{ | |
var webpack = new Webpack(){}; | |
} | |
@if (!string.IsNullOrEmpty(webpack.manifest)) | |
{ | |
@:<script> window.webpackManifest = @Html.Raw(webpack.manifest)</script> | |
} |
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
@using Test.Models; | |
@{ | |
var webpack = new Webpack(){}; | |
} | |
<script src="@webpack.common"></script> | |
<script src="@webpack.vendor"></script> | |
<script src="@webpack.app"></script> |
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
import fs, { writeFile, readFileSync } from 'fs'; | |
import { resolve, join } from 'path'; | |
import CleanWebpackPlugin from 'clean-webpack-plugin'; | |
import webpack, { optimize, DefinePlugin, LoaderOptionsPlugin } from 'webpack'; | |
import ChunkManifestPlugin from 'chunk-manifest-webpack-plugin'; | |
import SplitByPath from 'webpack-split-by-path'; | |
import WebpackMd5Hash from 'webpack-md5-hash'; | |
import WebpackShellPlugin from 'webpack-shell-plugin'; | |
import BellOnBundlerErrorPlugin from 'bell-on-bundler-error-plugin'; | |
import NpmInstall from 'npm-install-webpack-plugin'; | |
import ProgressBar from 'progress-bar-webpack-plugin'; | |
import { green, yellow, underline } from 'chalk'; | |
import Ora from 'ora'; | |
import merge from 'deepmerge'; | |
import './scripts/env.es6'; | |
import { Debug } from './scripts/debug.es6'; | |
import devConfig from './webpack.client.development.config'; | |
import prodConfig from './webpack.client.production.config'; | |
import requireAlias, { extDep } from './scripts/requirejsConfig'; | |
const debug = new Debug('webpack:config'); | |
const NODE_ENV = process.env.NODE_ENV; | |
const node_envString = green(`${NODE_ENV} webpack build`); | |
debug(underline(node_envString)); | |
/** | |
* Load .babelrc and override where necessary | |
* Webpack Tree shaking requires ES6 modules enabled. | |
*/ | |
const babelrcFile = readFileSync('.babelrc'); | |
const babelrcJson = JSON.parse(babelrcFile); | |
const babelrc = { | |
...babelrcJson, | |
babelrc: false, | |
}; | |
babelrc.presets.forEach((preset, index) => { | |
if (preset[0] === 'es2015') { | |
babelrc.presets[index][1].modules = false; | |
return; | |
} | |
}); | |
if (NODE_ENV === 'development') { | |
babelrc.plugins.push('react-hot-loader/babel'); | |
} | |
debug(`${yellow.bold('.babelrc =')} ${yellow(JSON.stringify(babelrc))}`); | |
/** | |
* Webpack settings shared for all ENV | |
* @type {Object} | |
*/ | |
const config = { | |
context: __dirname, | |
entry: { | |
heapp: './scripts/heapp.js', | |
}, | |
resolve: { | |
extensions: [ | |
'.js', | |
'.scss', | |
'.sass', | |
'.css', | |
'.jsx', | |
'.es6', | |
], | |
alias: { | |
...requireAlias, | |
modernizr$: resolve(__dirname, 'config/.modernizrrc'), | |
}, | |
modules: ['node_modules', 'scripts', 'assets/scss'], | |
}, | |
externals: { | |
...extDep, | |
}, | |
module: { | |
loaders: [ | |
{ | |
enforce: 'pre', | |
test: /\.es6$/, | |
exclude: [ | |
resolve(__dirname, 'node_modules'), | |
resolve(__dirname, 'scripts/dist'), | |
resolve(__dirname, 'scripts/ext-lib'), | |
], | |
loader: 'eslint', | |
query: { | |
configFile: 'config/eslint-config-es6.yml', | |
failOnError: false, | |
failOnWarning: false, | |
emitError: false, | |
emitWarning: false, | |
fix: true, | |
quiet: true, | |
}, | |
}, | |
{ | |
test: /\.[js|jsx]$/, | |
exclude: [ | |
resolve(__dirname, 'node_modules'), | |
resolve(__dirname, 'scripts/ext-lib'), | |
], | |
loader: 'babel', | |
query: babelrc, | |
}, | |
{ | |
test: /\.modernizrrc$/, | |
exclude: 'node_modules', | |
loader: 'modernizr', | |
}, | |
], | |
}, | |
plugins: [ | |
new SplitByPath ([ | |
{ | |
name: 'vendor', | |
path: [ | |
join(__dirname, 'node_modules'), | |
join(__dirname, 'scripts/ext-lib'), | |
] | |
}, | |
], { | |
manifest: 'common', | |
}), | |
new DefinePlugin({ | |
'process.env': { | |
'NODE_ENV': JSON.stringify(NODE_ENV), | |
}, | |
}), | |
new LoaderOptionsPlugin({ | |
minimize: true, | |
}), | |
new CleanWebpackPlugin([ | |
'bin/webpack.json', | |
'bin/assets', | |
], { | |
root: __dirname, | |
}), | |
new WebpackMd5Hash(), | |
new optimize.OccurrenceOrderPlugin(), | |
new WebpackShellPlugin({ | |
onBuildStart: [], | |
onBuildEnd: [], | |
}), | |
new NpmInstall({ | |
dev: false, | |
peerDependencies: true, | |
}), | |
new ProgressBar({ | |
format: `:╢:bar╟ :percent :eta`, | |
incomplete: '░', | |
complete: green('░'), | |
}), | |
function() { | |
this.plugin('done', stats => { | |
const spinner = new Ora('Exporting webpack stats to json file'); | |
const filePath = resolve(__dirname, 'bin/webpack.json'); | |
const statsJson = stats.toJson(); | |
statsJson.node_env = NODE_ENV; | |
const data = JSON.stringify(statsJson); | |
spinner.start(); | |
writeFile(filePath, data, err => { | |
if (err) { | |
spinner.fail(); | |
throw err; | |
} | |
spinner.succeed(); | |
}); | |
}); | |
}, | |
], | |
}; | |
const envConfig = (NODE_ENV === 'production') ? prodConfig : devConfig; | |
const webpackConfig = merge(config, envConfig); | |
webpackConfig.plugins = [ | |
...config.plugins, | |
...envConfig.plugins, | |
]; | |
export { webpackConfig as default } |
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
import { join } from 'path'; | |
import { LoaderOptionsPlugin } from 'webpack'; | |
/** | |
* Webpack settings required for development ENV | |
* @type {Object} | |
* @exports Object Webpack development config | |
*/ | |
export default { | |
devtool: 'source-map', | |
devServer: { | |
'content-base': 'scripts/dist', | |
inline: true, | |
'history-api-fallback': true, | |
https: false, | |
host: '0.0.0.0', | |
port: 5001, | |
compress: true, | |
colors: true, | |
hot: true, | |
}, | |
output: { | |
filename: '[name].js', | |
chunkFilename: '[name].js', | |
path: join(__dirname, 'scripts/dist'), | |
publicPath: '//localhost:5001/scripts/dist/', | |
}, | |
plugins: [ | |
new LoaderOptionsPlugin({ | |
minimize: true, | |
}), | |
], | |
}; |
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
import { resolve } from 'path'; | |
import webpack, { optimize } from 'webpack'; | |
import ManifestPlugin from 'webpack-manifest-plugin'; | |
/** | |
* Webpack settings required for Production ENV | |
* @type {Object} | |
* @exports Object Webpack production config | |
*/ | |
export default { | |
output: { | |
filename: '[name].[hash].js', | |
chunkFilename: '[name].[chunkhash].js', | |
path: './public/assets/[hash]', | |
publicPath: '/public/assets/[hash]/', | |
}, | |
plugins: [ | |
new ManifestPlugin({ | |
fileName: 'manifest.json', | |
}), | |
/*new optimize.UglifyJsPlugin({ | |
compress: { | |
warnings: false, | |
}, | |
comments: false, | |
}),*/ | |
new optimize.DedupePlugin(), | |
], | |
}; |
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
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Script.Serialization; | |
namespace Test.Models | |
{ | |
public class Webpack | |
{ | |
/// <summary> | |
/// Initializes a new instance of <see cref="Webpack"/> class | |
/// </summary> | |
/// <remarks>Webpack constructor</remarks> | |
public Webpack() | |
{ | |
this.Folder = "~/bin/"; | |
this.Name = "webpack"; | |
this.Extension = ".json"; | |
string webpackStatsFile = File.ReadAllText(Path); | |
this.json = JsonConvert.DeserializeObject<WebpackJson>(webpackStatsFile); | |
} | |
/// <summary> | |
/// Folder containing webpack json | |
/// </summary> | |
/// <value>The folder property gets/sets the folder path</value> | |
public string Folder { get; set; } | |
/// <summary> | |
/// Filename | |
/// </summary> | |
/// <value>The Name property gets/sets the name of requested icon.</value> | |
public string Name { get; set; } | |
/// <summary> | |
/// Extension used by webpack stats file | |
/// </summary> | |
/// <value>The Extension property gets/sets the extension used by the webpack stats file</value> | |
public string Extension { get; set; } | |
/// <summary> | |
/// The full path to the webpack stats file | |
/// </summary> | |
/// <value>The Path property gets the full file path</value> | |
private string Path | |
{ | |
get | |
{ | |
var path = Folder + Name + Extension; | |
return HttpContext.Current.Server.MapPath(path); | |
} | |
} | |
public new WebpackJson json { get; set; } | |
public string app | |
{ | |
get | |
{ | |
return json.publicPath + json.assetsByChunkName.app[0]; | |
} | |
} | |
public string common | |
{ | |
get | |
{ | |
return json.publicPath + json.assetsByChunkName.common[0]; | |
} | |
} | |
public string vendor | |
{ | |
get | |
{ | |
return json.publicPath + json.assetsByChunkName.vendor[0]; | |
} | |
} | |
public string node_env | |
{ | |
get | |
{ | |
return json.node_env; | |
} | |
} | |
public string manifest | |
{ | |
get | |
{ | |
if (node_env != "production") | |
{ | |
return "{}"; | |
} | |
string manifestPath = json.publicPath + "manifest.json"; | |
string serverPath = HttpContext.Current.Server.MapPath(manifestPath); | |
string manifest = File.ReadAllText(serverPath); | |
return manifest; | |
} | |
} | |
} | |
} |
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
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace Test.Models | |
{ | |
public class WebpackJson | |
{ | |
public object[] errors { get; set; } | |
public object[] warnings { get; set; } | |
public string version { get; set; } | |
public string hash { get; set; } | |
public int time { get; set; } | |
public string publicPath { get; set; } | |
public Assetsbychunkname assetsByChunkName { get; set; } | |
public Asset[] assets { get; set; } | |
public Entrypoints entrypoints { get; set; } | |
public Chunk[] chunks { get; set; } | |
public Module[] modules { get; set; } | |
public int filteredModules { get; set; } | |
public object[] children { get; set; } | |
public string node_env { get; set; } | |
public class Assetsbychunkname | |
{ | |
public string[] app { get; set; } | |
public string[] common { get; set; } | |
public string[] vendor { get; set; } | |
} | |
public class Entrypoints | |
{ | |
public App app { get; set; } | |
} | |
public class App | |
{ | |
public int[] chunks { get; set; } | |
public string[] assets { get; set; } | |
} | |
public class Asset | |
{ | |
public string name { get; set; } | |
public int size { get; set; } | |
public int?[] chunks { get; set; } | |
public string[] chunkNames { get; set; } | |
public bool emitted { get; set; } | |
} | |
public class Chunk | |
{ | |
public int id { get; set; } | |
public bool rendered { get; set; } | |
public bool initial { get; set; } | |
public bool entry { get; set; } | |
public bool extraAsync { get; set; } | |
public int size { get; set; } | |
public string[] names { get; set; } | |
public string[] files { get; set; } | |
public string hash { get; set; } | |
public int?[] parents { get; set; } | |
public string loc { get; set; } | |
public Origin[] origins { get; set; } | |
} | |
public class Origin | |
{ | |
public int moduleId { get; set; } | |
public string module { get; set; } | |
public string moduleIdentifier { get; set; } | |
public string moduleName { get; set; } | |
public string loc { get; set; } | |
public string name { get; set; } | |
public string[] reasons { get; set; } | |
} | |
public class Module | |
{ | |
public int id { get; set; } | |
public string identifier { get; set; } | |
public string name { get; set; } | |
public int index { get; set; } | |
public int index2 { get; set; } | |
public int size { get; set; } | |
public bool cacheable { get; set; } | |
public bool built { get; set; } | |
public bool optional { get; set; } | |
public bool prefetched { get; set; } | |
public int?[] chunks { get; set; } | |
public object[] assets { get; set; } | |
public string issuer { get; set; } | |
public int? issuerId { get; set; } | |
public string issuerName { get; set; } | |
public bool failed { get; set; } | |
public int errors { get; set; } | |
public int warnings { get; set; } | |
public Reason[] reasons { get; set; } | |
public bool usedExports { get; set; } | |
public object providedExports { get; set; } | |
public string source { get; set; } | |
} | |
public class Reason | |
{ | |
public int moduleId { get; set; } | |
public string moduleIdentifier { get; set; } | |
public string module { get; set; } | |
public string moduleName { get; set; } | |
public string type { get; set; } | |
public object userRequest { get; set; } | |
public string loc { get; set; } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment