123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- const path = require('path');
- const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
- // Webpack plugins.
- const { DefinePlugin } = require('webpack');
- const { LimitChunkCountPlugin } = require('webpack').optimize;
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const VirtualModulesPlugin = require('webpack-virtual-modules');
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
- const ProgressBarPlugin = require('progress-bar-webpack-plugin');
- const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
- const CopyPlugin = require("copy-webpack-plugin");
- var dotenv = require('dotenv').config({ path: path.resolve(__dirname + '../../../../.env') });
- import MyHtmlBeautifyWebpackPlugin from '../webpack-plugins/MyHtmlBeautifyWebpackPlugin';
- import { ConfigType, ConfigPages } from '../config';
- import defaultPages from './pagesConfig';
- import formatPagesConfig from './formatPagesConfig';
- function webpackEntry(env: string, srcDir: string, pages: ConfigPages) {
- const ret: { [key: string]: string } = {};
- for (const p in pages) {
- if ('development' === env || !pages[p].buildExclude) {
- ret[p] = path.resolve(srcDir + '/' + p + '.js');
- }
- }
- return ret;
- }
- function webpackOutput(env: string, destinationDir: string, buildDir?: string, chunkhash?: string, hash?: string) {
- const ret = {
- path: destinationDir,
- filename: '',
- };
- const prefix = 'development' === env ? '' : buildDir;
- let tmp;
- if (undefined !== chunkhash) {
- tmp = chunkhash.trim();
- if ('' === tmp) {
- throw Error('Invalid chunkhash argument value: ' + chunkhash);
- }
- ret.filename = (prefix || '') + '[name]-[chunkhash].js';
- }
- else if (undefined !== hash) {
- tmp = hash.trim();
- if ('' === tmp) {
- throw Error('Invalid hash argument value: ' + hash);
- }
- ret.filename = (prefix || '') + '[name]-[hash].js';
- }
- else {
- ret.filename = (prefix || '') + '[name].js';
- }
- return ret;
- }
- function webpackAlias() {
- return {
- // modernizr$: path.resolve(__dirname, "../../.modernizrrc"), // TODO: Enable this?
- };
- }
- function webpackRules(env: string, srcDir: string, postcssConfigFile: string): any[] {
- return [{
- test: /\.(jsx|js)?$/,
- use: 'babel-loader'
- },
- {
- test: /\.(tsx|ts)?$/,
- use: 'ts-loader',
- // exclude: /node_modules/,
- // options: {
- // compilerOptions: {
- // "sourceMap": !isProduction,
- // },
- // },
- },
- {
- test: /\.ejs$/,
- use: {
- loader: 'ejs-compiled-loader',
- options: {
- // beautify: true,
- htmlmin: true,
- // htmlminOptions: {
- // removeComments: true,
- // collapseWhitespace: true,
- // preserveLineBreaks: true
- // }
- }
- }
- },
- {
- test: /\.(sa|sc|c)ss$/,
- use: [
- { loader: MiniCssExtractPlugin.loader },
- // { loader: 'development' === env ? MiniCssExtractPlugin.loader : 'style-loader' }, // Use inline <style> tag.
- { loader: 'css-loader', options: { importLoaders: 1 } },
- { loader: 'postcss-loader', options: { postcssOptions: { config: postcssConfigFile } } },
- { loader: 'sass-loader' },
- ],
- },
- {
- test: /\.module\.(sa|sc|c)ss$/,
- use: [
- { loader: MiniCssExtractPlugin.loader },
- // { loader: 'development' === env ? MiniCssExtractPlugin.loader : 'style-loader' }, // Use inline <style> tag.
- { loader: 'css-loader', options: { importLoaders: 1, modules: true, onlyLocals: false } },
- { loader: 'postcss-loader', options: { postcssOptions: { config: postcssConfigFile } } },
- { loader: 'sass-loader' },
- ]
- },
- {
- test: /\.(png|jpe?g|gif)(\?\S*)?$/,
- use: {
- loader: 'url-loader',
- options: {
- limit: 1024,
- fallback: 'file-loader',
- name: (file: string) => {
- return '.' + path.join(file.replace(srcDir, ''), '..').replace(/\\/g, '/') + '/[name].[ext]';
- },
- },
- },
- },
- {
- test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
- /*issuer: {
- test: /\.jsx?$/
- },*/
- use: ['babel-loader', '@svgr/webpack', 'url-loader']
- },
- {
- test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
- loader: 'url-loader'
- },
- {
- test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
- use: [{
- loader: 'file-loader',
- options: {
- name: (file: string) => {
- return '.' + path.join(file.replace(srcDir, ''), '..').replace(/\\/g, '/') + '/[name].[ext]';
- },
- }
- }]
- },
- {
- test: /\.modernizrrc.js$/,
- use: 'modernizr-loader',
- },
- {
- test: /\.modernizrrc(\.json)?$/,
- use: ['modernizr-loader', 'json-loader'],
- }
- ];
- }
- function webpackPlugins(env: string, srcDir: string, pages: ConfigPages, cssSrc: string) {
- const ret = [
- new DefinePlugin({ "process.env": JSON.stringify(dotenv.parsed) }),
- new NodePolyfillPlugin(),
- new MyHtmlBeautifyWebpackPlugin(),
- ];
- if ('development' !== env) {
- ret.push(
- new CopyPlugin({
- patterns: [
- {
- from: path.resolve(__dirname, '../../../src/static/lib'),
- to: path.resolve(__dirname, '../../../' + env + '/static/lib'),
- },
- {
- from: path.resolve(__dirname, '../../../src/static/images'),
- to: path.resolve(__dirname, '../../../' + env + '/static/images'),
- },
- {
- from: path.resolve(__dirname, '../../../src/static/favicons'),
- to: path.resolve(__dirname, '../../../' + env + '/static/favicons'),
- },
- {
- from: path.resolve(__dirname, '../../../src/static/css/_extra.css'),
- to: path.resolve(__dirname, '../../../' + env + '/static/css/_extra.css'),
- },
- ],
- })
- );
- }
- const virtualPages: { [key: string]: string } = {};
- let file: string;
- for (const k in pages) {
- if ('production' !== env || !pages[k].buildExclude) {
- file = path.resolve(srcDir + '/' + k + '.js');
- if ((void 0 !== pages[k].staticPage && pages[k].staticPage) || void 0 === pages[k].render) {
- virtualPages[file] = '';
- } else {
- virtualPages[file] = pages[k].render;
- }
- }
- if ('development' === env) {
- // Export pages HTML files.
- ret.push(new HtmlWebpackPlugin({
- template: path.resolve(__dirname, '../templates/index.ejs'),
- hash: false,
- chunks: [k],
- ...pages[k],
- }));
- }
- }
- ret.push(new VirtualModulesPlugin(virtualPages));
- ret.push(new MiniCssExtractPlugin({
- ignoreOrder: true, // TODO: Remove it...
- // filename: ! is_build ? '[name].css' : '[name].[hash].css',
- // chunkFilename: ! is_build ? '[id].css' : '[id].[hash].css',
- filename: cssSrc + '[name].css',
- // chunkFilename: "../css/[id].css",
- }));
- if ('development' !== env) {
- ret.push(new LimitChunkCountPlugin({ maxChunks: 1 }));
- ret.push(
- new ProgressBarPlugin({
- clear: false,
- })
- );
- }
- if ('production' === env) {
- ret.push(new CssMinimizerPlugin({
- cache: true, // TODO: Ignore in Webpack 5. Use https://webpack.js.org/configuration/other-options/#cache.
- minimizerOptions: {
- preset: [
- 'default',
- {
- discardComments: { removeAll: true },
- },
- ],
- },
- }));
- }
- return ret;
- }
- export default function generateConfig(env: string, config: ConfigType) {
- const srcDir = config.src;
- const buildDir = config.build + '/' + env + ('development' === env ? '' : '/static');
- const cssbuild = './css/';
- const jsbuild = './js/';
- const configPages = config.pages;
- const configPagesKeys = config.pages ? Object.keys(configPages) : [];
- const defPages = defaultPages(configPagesKeys);
- const pages = formatPagesConfig(
- { title: '', filename: '', render: '', html: config.html, window: config.window },
- { ...configPages, ...defPages }
- );
- const ret = {
- entry: webpackEntry(env, srcDir, pages),
- output: 'development' === env ? webpackOutput(env, srcDir, void 0, void 0, void 0) : webpackOutput(env, buildDir, jsbuild, void 0, void 0),
- plugins: webpackPlugins(env, srcDir, pages, cssbuild),
- module: {
- rules: webpackRules(env, srcDir, config.postcssConfigFile),
- },
- resolve: {
- alias: webpackAlias(),
- extensions: ['.tsx', '.ts', '.jsx', '.js'],
- },
- };
- return ret;
- }
|