Skip to content

Commit

Permalink
chore: cleanup code
Browse files Browse the repository at this point in the history
  • Loading branch information
itsdouges committed Mar 22, 2021
1 parent ad0c336 commit 008d8e9
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 67 deletions.
85 changes: 23 additions & 62 deletions packages/webpack-loader/src/extract-plugin.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { sort } from '@compiled/css';
import { toBoolean } from '@compiled/utils';
import type { Compiler, Compilation, sources } from 'webpack';
import type { Compiler, Compilation } from 'webpack';
import type { CompiledExtractPluginOptions } from './types';
import {
getAssetSourceContents,
getNormalModuleHook,
getOptimizeAssetsHook,
getSources,
} from './utils/webpack';

export const pluginName = 'CompiledExtractPlugin';
export const styleSheetName = 'compiled-css';
Expand All @@ -21,21 +27,6 @@ const getCSSAssets = (assets: Compilation['assets']) => {
.map((assetName) => ({ name: assetName, source: assets[assetName], info: {} }));
};

/**
* Returns the string representation of an assets source.
*
* @param source
* @returns
*/
const getAssetSourceContents = (assetSource: sources.Source) => {
const source = assetSource.source();
if (typeof source === 'string') {
return source;
}

return source.toString();
};

/**
* Set a cache group to force all CompiledCSS found to be in a single style sheet.
* We do this to simplify the sorting story for now. Later on we can investigate
Expand Down Expand Up @@ -78,7 +69,7 @@ const forceCSSIntoOneStyleSheet = (compiler: Compiler) => {
*
* @param compiler
*/
const applyExtractFromNodeModule = (
const pushNodeModulesExtractLoader = (
compiler: Compiler,
options: CompiledExtractPluginOptions
): void => {
Expand Down Expand Up @@ -114,60 +105,30 @@ export class CompiledExtractPlugin {
}

apply(compiler: Compiler): void {
const { NormalModule, Compilation, version, sources: wp5sources } =
// Webpack 5 flow
compiler.webpack ||
// Override flow
this.#options.webpack ||
// Webpack 4 flow
require('webpack');

const sources = wp5sources || require('webpack-sources');
const isWebpack4 = version.startsWith('4.');

applyExtractFromNodeModule(compiler, this.#options);
const { RawSource } = getSources(compiler);

pushNodeModulesExtractLoader(compiler, this.#options);
forceCSSIntoOneStyleSheet(compiler);

compiler.hooks.compilation.tap(pluginName, (compilation) => {
const normalModuleHook =
NormalModule && typeof NormalModule.getCompilationHooks !== 'undefined'
? // Webpack 5 flow
NormalModule.getCompilationHooks(compilation).loader
: // Webpack 4 flow
compilation.hooks.normalModuleLoader;

normalModuleHook.tap(pluginName, (loaderContext) => {
getNormalModuleHook(compiler, compilation).tap(pluginName, (loaderContext) => {
// We add some information here to tell loaders that the plugin has been configured.
// Bundling will throw if this is missing (i.e. consumers did not setup correctly).
(loaderContext as any)[pluginName] = true;
});

const optimizeAssets =
// Webpack 5 flow
compilation.hooks.processAssets ||
// Webpack 4 flow
compilation.hooks.optimizeAssets;

optimizeAssets.tap(
isWebpack4
? pluginName
: {
name: pluginName,
stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
},
(assets) => {
const cssAssets = getCSSAssets(assets);
if (cssAssets.length === 0) {
return;
}

const [asset] = cssAssets;
const contents = getAssetSourceContents(asset.source);
const newSource = new sources.RawSource(sort(contents));

compilation.updateAsset(asset.name, newSource, asset.info);
getOptimizeAssetsHook(compiler, compilation).tap(pluginName, (assets) => {
const cssAssets = getCSSAssets(assets);
if (cssAssets.length === 0) {
return;
}
);

const [asset] = cssAssets;
const contents = getAssetSourceContents(asset.source);
const newSource = new RawSource(sort(contents));

compilation.updateAsset(asset.name, newSource, asset.info);
});
});
}
}
5 changes: 0 additions & 5 deletions packages/webpack-loader/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,4 @@ export interface CompiledExtractPluginOptions {
* See: https://webpack.js.org/configuration/module/#condition
*/
nodeModulesExclude?: RuleSetCondition;

/**
* @deprecated
*/
webpack?: any;
}
95 changes: 95 additions & 0 deletions packages/webpack-loader/src/utils/webpack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type { Compiler, Compilation as CompilationType, sources } from 'webpack';

/**
* Gets the normal module hook for webpack 4 & webpack 5.
*
* @returns
*/
export const getNormalModuleHook = (
compiler: Compiler,
compilation: CompilationType
): CompilationType['hooks']['normalModuleLoader'] => {
const { NormalModule } =
// Webpack 5 flow
compiler.webpack ||
// Webpack 4 flow
require('webpack');

const normalModuleHook =
NormalModule && typeof NormalModule.getCompilationHooks !== 'undefined'
? // Webpack 5 flow
NormalModule.getCompilationHooks(compilation).loader
: // Webpack 4 flow
compilation.hooks.normalModuleLoader;

return normalModuleHook;
};

/**
* Returns the string representation of an assets source.
*
* @param source
* @returns
*/
export const getAssetSourceContents = (assetSource: sources.Source): string => {
const source = assetSource.source();
if (typeof source === 'string') {
return source;
}

return source.toString();
};

/**
* Returns a webpack 4 & 5 compatible hook for optimizing assets.
*
* @param compilation
* @returns
*/
export const getOptimizeAssetsHook = (
compiler: Compiler,
compilation: CompilationType
): { tap: CompilationType['hooks']['processAssets']['tap'] } => {
const { Compilation, version } =
// Webpack 5 flow
compiler.webpack ||
// Webpack 4 flow
require('webpack');
const isWebpack4 = version.startsWith('4.');
const optimizeAssets =
// Webpack 5 flow
compilation.hooks.processAssets ||
// Webpack 4 flow
compilation.hooks.optimizeAssets;

return {
tap: (pluginName: string, callback: (assets: CompilationType['assets']) => void) => {
optimizeAssets.tap(
isWebpack4
? pluginName
: {
name: pluginName,
stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
},
callback
);
},
};
};

/**
* Returns webpack 4 & 5 compatible sources.
* @returns
*/
export const getSources = (compiler: Compiler): typeof sources => {
const { sources } =
// Webpack 5 flow
compiler.webpack;

return (
// Webpack 5 flow
sources ||
// Webpack 4 flow
require('webpack-sources')
);
};

0 comments on commit 008d8e9

Please sign in to comment.