Skip to content

Instantly share code, notes, and snippets.

@owlyowl
Created July 3, 2019 08:14
Show Gist options
  • Save owlyowl/a23a9799a0a213fee80b0540baa6469b to your computer and use it in GitHub Desktop.
Save owlyowl/a23a9799a0a213fee80b0540baa6469b to your computer and use it in GitHub Desktop.
const stripJsonComments = require('strip-json-comments');
const fs = require('fs');
const merge = require('webpack-merge');
const path = require('path');
const siteLessPlugins = require('../Theme/plugins/site');
const getCurrentTheme = () => {
const AppSettings = JSON.parse(stripJsonComments(fs.readFileSync('./appsettings.Development.json').toString()));
if (AppSettings && AppSettings.ThemeConfig && AppSettings.ThemeConfig.ThemeName) {
return AppSettings.ThemeConfig.ThemeName;
}
return 'site';
};
const themes = ['site', 'blue', 'grey', 'red', 'green', 'yellow'];
const getThemeConfig = (miniCssLoader, themeNameToPassInToLess, isDevBuild) => {
return {
test: /\.(css|less)$/,
use: [(isDevBuild ? 'style-loader' : { loader: miniCssLoader, options: { disabled: isDevBuild } }),
'css-loader',
'resolve-url-loader',
{
loader: "less-loader",
options: {
plugins: [siteLessPlugins],
globalVars: {
themeName: themeNameToPassInToLess
}
}
}]
};
};
module.exports = {
getThemeConfig,
getCurrentTheme,
getThemeConfigs: (miniCssLoader, sharedConfig, bundleOutputDir, isDevBuild) => {
const result = [];
for (const theme of themes) {
result.push(merge({
entry: {
[theme]: './Theme/sites/site.less'
},
output: {
path: path.join(__dirname, bundleOutputDir),
filename: '[name].[chunkhash].css',
publicPath: '/dist/'
},
module: {
rules: [getThemeConfig(miniCssLoader, theme, isDevBuild)]
}
}, sharedConfig));
}
return result;
}
};
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const StatsWriterPlugin = require("webpack-stats-plugin").StatsWriterPlugin;
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const bundleOutputDir = './wwwroot/dist';
const themeHelpers = require('./Webpack/themes');
let stats = {};
function recursiveIssuer(m) {
if (m.issuer) {
return recursiveIssuer(m.issuer);
} else if (m.name) {
return m.name;
} else {
return false;
}
}
const cpus = require('os').cpus().length;
const settings = fs.existsSync('./webpackSettings.json') ?
require('./webpackSettings.json') : {
typeCheckerWorkers: Math.min(2, cpus),
transpilerWorkers: Math.max(1, cpus - 3),
typeCheckingOverlay: true,
};
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
const sharedConfig = {
mode: !isDevBuild ? 'production' : 'development',
optimization: {
minimizer: [new TerserJSPlugin({})/*, new OptimizeCSSAssetsPlugin({})*/]
},
devtool: isDevBuild ? 'source-map' : false,
stats: {
modules: false
},
resolve: {
extensions: ['.js', '.jsx', 'json', '.ts', '.tsx', '.modern'],
modules: ['.', './', 'node_modules'],
alias: {
'../../theme.config$': path.join(__dirname, 'Theme/theme.config')
}
},
module: {
rules: [
{
test: /\.(png|jpg|jpeg|gif|svg)$/,
use: 'url-loader?limit=25000'
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/fontwoff'
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader?name=public/fonts/[name].[ext]'
}
]
},
plugins: [new MiniCssExtractPlugin({
disable: isDevBuild,
moduleFilename: (chunkData) => {
console.log('--- MODULE CHUNK DATA ---', chunkData);
if (chunkData.name.includes('admin') || chunkData.name.includes('client') || chunkData.name.includes('login')) {
return 'app.css';
}
return chunkData.name + '.css';
},
}),
new ForkTsCheckerWebpackPlugin({
workers: settings.typeCheckerWorkers,
async: !settings.typeCheckingOverlay,
useTypescriptIncrementalApi: false
})
]
.concat(settings.typeCheckingOverlay ? [] : [new ForkTsCheckerNotifierWebpackPlugin()])
.concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("development")
}
})
] : [
// Plugins that apply in production builds only
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
})
//We don't need to define our own minimizer plugin unless we really want to
//because webpack 4 includes terser minificaiton out of the box if mode: production
])
};
const clientConfig = merge({
entry: {
'main-client': './ClientApp/boot.tsx',
'login': './LoginApp/boot.tsx',
'admin': './AdminApp/boot.tsx'
},
module: {
rules: [{
test: /\.tsx?$/,
exclude: /node_modules/,
include: /ClientApp|LoginApp|AdminApp|CommonApp/,
use: [
`ifdef-loader?isDevBuild=${isDevBuild}`,
{
loader: 'awesome-typescript-loader',
options: {
silent: true,
transpileOnly: true,
useCache: true
}
}]
},
themeHelpers.getThemeConfig(MiniCssExtractPlugin.loader, themeHelpers.getCurrentTheme())]
},
output: {
path: path.join(__dirname, bundleOutputDir),
filename: isDevBuild ? '[name].js' : '[name].[chunkhash].js',
publicPath: '/dist/'
},
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
}),
new StatsWriterPlugin({
filename: '../../webpackstats.json',
transform(data) {
stats.assetsByChunkName = Object.assign({}, stats.assetsByChunkName, data.assetsByChunkName);
return JSON.stringify(stats, null, 4);
}
}) // Used by ScriptTagHelper
]
}, sharedConfig);
if (isDevBuild) {
return clientConfig;
}
const themeConfigs = themeHelpers.getThemeConfigs(MiniCssExtractPlugin.loader, sharedConfig, '.' + bundleOutputDir, isDevBuild);
return [...themeConfigs, clientConfig];
};
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/dist/";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ })
/******/ ]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment