Skip to content
Draft
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"babel-loader": "^8.2.2",
"browser-sync": "^2.26.7",
"browserslist-config-webfactory": "^1.0.0",
"css-loader": "^7.1.2",
"dotenv": "^10.0.0",
"fancy-log": "^1.3.3",
"gulp": "^4.0.0",
Expand All @@ -22,10 +23,14 @@
"gulp-stylelint": "^13.0.0",
"gulp-svgmin": "^4.1.0",
"gulp-terser": "^2.0.1",
"mini-css-extract-plugin": "^2.9.4",
"minimist": "^1.2.0",
"postcss": "^8.0.9",
"postcss-loader": "^8.2.0",
"postcss-preset-env": "^9.3.0",
"postcss-url": "^10.1.3",
"resolve-url-loader": "^5.0.0",
"sass-loader": "^16.0.5",
"stylelint": "^14.1.0",
"stylelint-config-sass-guidelines": "^9.0.1",
"stylelint-order": "^5.0.0",
Expand Down
116 changes: 116 additions & 0 deletions tasks/stylepack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const postcssPurgecss = require("@fullhuman/postcss-purgecss");
const argv = require('minimist')(process.argv.slice(2));
const webpackStream = require('webpack-stream');
const mergeStream = require('merge-stream');
const path = require('path');

// This custom extractor will also match selectors that contain
// special chars like "_", ".", ":", "\" and "@"
function utilityCssExtractor(content) {
return content.match(/[a-zA-Z0-9-_.:@\/]+/g)
}

function stylepack(gulp, $, config) {

const streams = config.styles.files.map((file) => {
// Set up PurgeCSS with external config
let purgeCssConfig = file.purgeCss ?? config.styles.purgeCss;
let purgeCssDisabled = argv.purgecss === false; // Check for CLI flags/args
let purgeCss = purgeCssConfig && !purgeCssDisabled; // Determine if PurgeCSS should run

// Grab a PostCSS Preset Env config to use;
// always prefers a stylesheet-specific one over a global config for all CSS files
let postCssPresetEnvConfig = file.postCssPresetEnv || config.styles.postCssPresetEnv || '';

const webpackConfig = {
entry: `/${config.webdir}/${file.files}`,
output: {
// path: path.resolve(__dirname, 'webpack-tmp', file.destDir || ''),
filename: `webpack-tmp/${file.name}`,
},
resolve: {
mainFields: ['browser', 'module', 'main'],
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg|webp|avif)$/i,
type: 'asset/resource',
generator: {
filename: 'img/[name].[hash][ext]'
}
},
{
test: /\.s[ac]ss$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
sourceMap: true,
}
},
{
loader: 'resolve-url-loader',
},
{
loader: "postcss-loader",
options: {
sourceMap: true,
postcssOptions: {
plugins: [
["postcss-preset-env", postCssPresetEnvConfig],
purgeCss ? postcssPurgecss({
content: purgeCssConfig.content,
extractors: [
{
extractor: utilityCssExtractor,
extensions: ['php', 'twig', 'js', 'svg']
}
],
safelist: purgeCssConfig.safelist,
}) : false,
].filter(Boolean),
},
},
},
{
loader: 'sass-loader',
options: {
implementation: 'sass-embedded',
api: 'modern',
sourceMap: true,
sassOptions: {
loadPaths: config.styles.includePaths ? config.styles.includePaths : [config.npmdir]
},
},
},
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: `${file.destDir}/${file.name}`,
}),
],
mode: config.development && $.argv.prod !== true ? 'development' : 'production',
devtool: $.argv.debug === true ? 'source-map' : false,
stats: {
preset: 'normal',
timings: true
},
};

return webpackStream(webpackConfig)
.pipe(gulp.dest(path.join(config.webdir)));
});

return mergeStream(...streams)
.pipe($.browserSync.reload({ stream: true }));
}

exports.stylepack = stylepack;