Skip to content

Commit

Permalink
feat(settings): 支持异步的finalize函数 (#233)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: 配置中的`build.scripts.finalize`调整为异步函数

BREAKING CHANGE: 配置中的`build.finalize`调整为异步函数

BREAKING CHANGE: 配置中的`devServer.finalize`调整为异步函数

BREAKING CHANGE: 配置中的`build.scripts.finalize`的`internals`参数中的`loaders`和`rules`均调整为异步函数

BREAKING CHANGE: `@reskript/config-webpack`不再导出`loaders`和`rules`,对应为`@reskript/config-webpack/loaders`和`@reskript/config-webpack/rules`

BREAKING CHANGE: `loaders.postCSS`重命名为`loaders.postcss`

BREAKING CHANGE: `loaders.postCSSModules`已经移除,功能与`loaders.postcss`完全一致
  • Loading branch information
otakustay committed Jan 29, 2022
1 parent 1950ace commit ce84916
Show file tree
Hide file tree
Showing 41 changed files with 160 additions and 145 deletions.
5 changes: 3 additions & 2 deletions packages/cli-play/src/webpack.ts
Expand Up @@ -2,7 +2,8 @@ import path from 'path';
import webpack from 'webpack';
import {reject, isNil} from 'ramda';
import {dirFromImportMeta} from '@reskript/core';
import {createWebpackConfig as createBaseWebpackConfig, BuildContext, loaders} from '@reskript/config-webpack';
import {createWebpackConfig as createBaseWebpackConfig, BuildContext} from '@reskript/config-webpack';
import * as loaders from '@reskript/config-webpack/loaders';
import {createWebpackDevServerPartial} from '@reskript/config-webpack-dev-server';
import {resolveComponentName} from './utils/path.js';
import {PlayCommandLineArgs} from './interface.js';
Expand All @@ -20,7 +21,7 @@ export const createWebpackConfig = async (target: string, cmd: PlayCommandLineAr
: path.join(currentDirectory, 'assets', 'playground-entry.js.tpl');
const componentTypeName = resolveComponentName(target);
const entryLoaders = [
loaders.babel(buildContext),
await loaders.babel(buildContext),
{
loader: path.join(currentDirectory, 'loader'),
options: {
Expand Down
9 changes: 6 additions & 3 deletions packages/config-img-loader/package.json
Expand Up @@ -2,9 +2,12 @@
"name": "@reskript/config-img-loader",
"version": "3.0.6",
"license": "MIT",
"type": "commonjs",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": "./dist/index.js"
},
"engines": {
"node": ">=14.18.0"
},
Expand All @@ -24,11 +27,11 @@
"@types/imagemin-gifsicle": "^7.0.1",
"@types/imagemin-mozjpeg": "^8.0.1",
"@types/imagemin-optipng": "^5.2.1",
"@types/jest": "^27.0.3",
"@types/node": "^17.0.4",
"@types/resolve": "^1.20.1",
"eslint": "^8.6.0",
"typescript": "4.6.0-dev.20220105"
"typescript": "4.6.0-dev.20220105",
"webpack": "^5.65.0"
},
"dependencies": {
"imagemin": "^7.0.1",
Expand Down
3 changes: 2 additions & 1 deletion packages/config-img-loader/src/index.ts
@@ -1,4 +1,5 @@
import resolve from 'resolve';
import {RuleSetUseItem} from 'webpack';
import gif from 'imagemin-gifsicle';
import jpeg from 'imagemin-mozjpeg';
import png from 'imagemin-optipng';
Expand All @@ -17,7 +18,7 @@ const pluginOptions = {
},
};

export default () => {
export default (): RuleSetUseItem => {
const plugins = [
gif(pluginOptions.gifsicle),
jpeg(pluginOptions.mozjpeg),
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack-dev-server/src/index.ts
Expand Up @@ -113,7 +113,7 @@ export const createWebpackDevServerConfig = async (buildEntry: BuildEntry, optio
{devServer: baseConfig},
{devServer: extra}
);
const finalized = buildEntry.projectSettings.devServer.finalize(mergedConfig.devServer, buildEntry);
const finalized = await buildEntry.projectSettings.devServer.finalize(mergedConfig.devServer, buildEntry);
warnAndExitOnInvalidFinalizeReturn(finalized, 'devServer');
return finalized;
};
Expand Down
7 changes: 3 additions & 4 deletions packages/config-webpack/README.md
Expand Up @@ -79,7 +79,7 @@ const createBuildConfiguration = async () => {
如果默认的构建配置外加`reskript.config.js`无法满足,或需要在`reskript.config.js`中的`build.finalize`部分复用一些默认的配置,则可以使用`loaders`对象来创建不同的loader配置:

```typescript
import {loaders} from '@reskript/config-webpack';
import * as loaders from '@reskript/config-webpack/loaders';

loaders: {
babel,
Expand All @@ -88,8 +88,7 @@ loaders: {
less,
css,
cssModules,
postCSS,
postCSSModules,
postcss,
style,
styleResources,
classNames,
Expand All @@ -112,7 +111,7 @@ interface BuildEntry extends RuntimeBuildEnv {
readonly buildTarget: string;
}

type LoaderFactory = (entry: BuildEntry) => RuleSetLoader | null;
type LoaderFactory = (entry: BuildEntry) => Promise<RuleSetLoader | null>;
```

`BuildEntry`是上文`BuildContext`的子集,参考相同的方式来构建这个对象。
Expand Down
5 changes: 4 additions & 1 deletion packages/config-webpack/package.json
Expand Up @@ -6,7 +6,9 @@
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": "./dist/index.js"
".": "./dist/index.js",
"./loaders": "./dist/loaders/index.js",
"./rules": "./dist/rules/index.js"
},
"engines": {
"node": ">=14.18.0"
Expand All @@ -24,6 +26,7 @@
"test": "vitest run"
},
"devDependencies": {
"@reskript/config-img-loader": "3.0.6",
"@types/cssnano": "^5.0.0",
"@types/less": "^3.0.3",
"@types/node": "^17.0.4",
Expand Down
5 changes: 2 additions & 3 deletions packages/config-webpack/src/index.ts
Expand Up @@ -10,7 +10,6 @@ import {
warnAndExitOnInvalidFinalizeReturn,
BuildInternals,
} from '@reskript/settings';
import * as loaders from './loaders/index.js';
import * as rules from './rules/index.js';
import {revision, hasServiceWorker} from './utils/info.js';
import {mergeBuiltin} from './utils/merge.js';
Expand All @@ -21,7 +20,7 @@ import {introduceLoader, introduceLoaders} from './utils/loader.js';
import {AppEntry, BuildContext, EntryLocation, StrictOptions} from './interface.js';
import {partials, strict as strictPartial} from './partials/index.js';

export {loaders, rules, createHTMLPluginInstances};
export {createHTMLPluginInstances};
export * from './interface.js';

export const collectEntries = async (location: EntryLocation): Promise<AppEntry[]> => {
Expand Down Expand Up @@ -84,7 +83,7 @@ export const createWebpackConfig = async (context: BuildContext, options: Option
loader: introduceLoader,
loaders: introduceLoaders,
};
const finalized = context.projectSettings.build.finalize(internalCreated, context, internals);
const finalized = await context.projectSettings.build.finalize(internalCreated, context, internals);
warnAndExitOnInvalidFinalizeReturn(finalized, 'build');
return finalized;
};
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/interface.ts
Expand Up @@ -29,7 +29,7 @@ export interface BuildContext extends RuntimeBuildEnv {
readonly entries: AppEntry[];
}

export type LoaderFactory = (entry: BuildEntry) => RuleSetUseItem | null;
export type LoaderFactory = (entry: BuildEntry) => Promise<RuleSetUseItem | null>;

export type ConfigurationFactory = (entry: BuildContext) => Configuration | Promise<Configuration>;

Expand Down
4 changes: 2 additions & 2 deletions packages/config-webpack/src/loaders/babel.ts
Expand Up @@ -3,7 +3,7 @@ import {getBabelConfig, BabelConfigOptions} from '@reskript/config-babel';
import {BuildEntry, warnAndExitOnInvalidFinalizeReturn} from '@reskript/settings';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = (entry: BuildEntry) => {
const factory: LoaderFactory = async (entry: BuildEntry) => {
const {usage, mode, cwd, srcDirectory, projectSettings: {build, devServer}} = entry;
const {uses, script: {polyfill, displayName}} = build;
const {hot} = devServer;
Expand All @@ -20,7 +20,7 @@ const factory: LoaderFactory = (entry: BuildEntry) => {
openInEditorPrefix: ':origin/__open_in_editor__?file=',
};
const internalCreatedBabelConfig = getBabelConfig(babelConfigOptions);
const finalizedBabelConfig = build.script.finalize(internalCreatedBabelConfig, entry);
const finalizedBabelConfig = await build.script.finalize(internalCreatedBabelConfig, entry);
warnAndExitOnInvalidFinalizeReturn(finalizedBabelConfig, 'build.script');

return {
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/classNames.ts
@@ -1,7 +1,7 @@
import {resolveSync} from '@reskript/core';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = () => {
const factory: LoaderFactory = async () => {
return {
loader: resolveSync('@ecomfe/class-names-loader'),
options: {
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/css.ts
@@ -1,7 +1,7 @@
import {resolveSync} from '@reskript/core';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = entry => {
const factory: LoaderFactory = async entry => {
return {
loader: resolveSync('css-loader'),
options: {
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/cssExtract.ts
@@ -1,7 +1,7 @@
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = () => {
const factory: LoaderFactory = async () => {
return {
loader: MiniCssExtractPlugin.loader,
};
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/cssModules.ts
Expand Up @@ -13,7 +13,7 @@ const generateScopedStyleName = (name: string, filename: string): string => {
};


const factory: LoaderFactory = entry => {
const factory: LoaderFactory = async entry => {
return {
loader: resolveSync('css-loader'),
options: {
Expand Down
8 changes: 3 additions & 5 deletions packages/config-webpack/src/loaders/img.ts
@@ -1,15 +1,13 @@
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = ({mode}) => {
const factory: LoaderFactory = async ({mode}) => {
if (mode !== 'production') {
return null;
}

try {
// TODO: 这玩意在ESM下没法玩
// eslint-disable-next-line global-require
const {default: loader} = require('@reskript/config-img-loader');
return loader;
const {default: loaderFactory} = await import('@reskript/config-img-loader');
return loaderFactory();
}
catch {
return null;
Expand Down
3 changes: 1 addition & 2 deletions packages/config-webpack/src/loaders/index.ts
Expand Up @@ -2,8 +2,7 @@ export {default as babel} from './babel.js';
export {default as style} from './style.js';
export {default as css} from './css.js';
export {default as cssModules} from './cssModules.js';
export {default as postCSS} from './postCSS.js';
export {default as postCSSModules} from './postCSSModules.js';
export {default as postcss} from './postcss.js';
export {default as less} from './less.js';
export {default as lessSafe} from './lessSafe.js';
export {default as img} from './img.js';
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/less.ts
Expand Up @@ -3,7 +3,7 @@ import NpmImport from 'less-plugin-npm-import';
import LessPluginFunctions from 'less-plugin-functions';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = ({projectSettings}) => {
const factory: LoaderFactory = async ({projectSettings}) => {
const {build: {style: {lessVariables, extract}}} = projectSettings;

return {
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/lessSafe.ts
@@ -1,7 +1,7 @@
import {resolveSync} from '@reskript/core';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = () => {
const factory: LoaderFactory = async () => {
return {
loader: resolveSync('@reskript/less-safe-loader'),
};
Expand Down
33 changes: 0 additions & 33 deletions packages/config-webpack/src/loaders/postCSSModules.ts

This file was deleted.

@@ -1,21 +1,22 @@
import {resolveSync, compact} from '@reskript/core';
import {resolveSync, compact, resolveFrom} from '@reskript/core';
import postCSS from 'postcss';
// import tailwind from 'tailwindcss';
import presetEnv from 'postcss-preset-env';
import nano from 'cssnano';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = ({mode, projectSettings}) => {
// const {build: {style: {extract}, uses}} = projectSettings;
const {build: {style: {extract}}} = projectSettings;
const factory: LoaderFactory = async ({mode, projectSettings}) => {
const {cwd, build: {style: {extract}, uses}} = projectSettings;

const importTailwind = async () => {
const resolve = resolveFrom(cwd);
const location = await resolve('tailwindcss');
const {default: tailwind} = await import(location);
return tailwind;
};
const plugins = [
// TODO: `tailwindcss`要用户安装,这里就要按需`import`了,为了不异步,要想办法包一层
/* eslint-disable global-require */
// uses.includes('tailwind') && tailwind,
uses.includes('tailwind') && await importTailwind(),
presetEnv(),
mode === 'production' ? nano() : null,
/* eslint-enable global-require */
];

return {
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/style.ts
@@ -1,7 +1,7 @@
import {resolveSync} from '@reskript/core';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = () => {
const factory: LoaderFactory = async () => {
return {
loader: resolveSync('style-loader'),
};
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/styleResources.ts
Expand Up @@ -3,7 +3,7 @@ import {resolveSync, compact} from '@reskript/core';
import unixify from 'unixify';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = ({cwd, srcDirectory, projectSettings}) => {
const factory: LoaderFactory = async ({cwd, srcDirectory, projectSettings}) => {
const {build: {style: {resources}}} = projectSettings;
const patterns = [
...resources,
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/svgToComponent.ts
@@ -1,7 +1,7 @@
import {resolveSync} from '@reskript/core';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = entry => {
const factory: LoaderFactory = async entry => {
const {mode, projectSettings: {build: {script: {displayName}}}} = entry;

return {
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/svgo.ts
@@ -1,7 +1,7 @@
import {resolveSync} from '@reskript/core';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = () => {
const factory: LoaderFactory = async () => {
return {
loader: resolveSync('svgo-loader'),
options: {
Expand Down
2 changes: 1 addition & 1 deletion packages/config-webpack/src/loaders/worker.ts
@@ -1,7 +1,7 @@
import {resolveSync} from '@reskript/core';
import {LoaderFactory} from '../interface.js';

const factory: LoaderFactory = () => {
const factory: LoaderFactory = async () => {
return {
loader: resolveSync('worker-loader'),
options: {
Expand Down
3 changes: 2 additions & 1 deletion packages/config-webpack/src/partials/base.ts
Expand Up @@ -152,6 +152,7 @@ const factory: ConfigurationFactory = async entry => {
reportLintErrors && usage === 'build' && new StyleLintPlugin(styleLintOptions),
];
const cacheKey = await computeCacheKey(entry);
const moduleRules = await Promise.all(Object.values(rules).map(rule => rule(entry)));

return {
mode,
Expand All @@ -170,7 +171,7 @@ const factory: ConfigurationFactory = async entry => {
publicPath: publicPath || '/assets/',
},
module: {
rules: Object.values(rules).map(rule => rule(entry)),
rules: moduleRules,
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts'],
Expand Down

0 comments on commit ce84916

Please sign in to comment.