Skip to content

Commit

Permalink
feat: add the pulicMiddleware (#1673)
Browse files Browse the repository at this point in the history
* feat: add the pulicMiddleware

* feat: add the logger for the publicMiddleware

---------

Co-authored-by: zengwenjie.paq <zengwenjie.paq@bytedance.com>
Co-authored-by: ADNY <66500121+ErKeLost@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 30, 2024
1 parent 3ffa686 commit 69391da
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 28 deletions.
5 changes: 3 additions & 2 deletions examples/public-dir/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React, { useState } from "react";
import "./main.css";
import reactLogo from "./assets/react.svg";
// import FarmLogo from "../public/logo.png";
import FarmLogo from "/new-logo.png";
// import FarmLogo from "../newPublic/new-logo.png";
export function Main() {
const [count, setCount] = useState(0);

return (
<>
<div>
<a href="https://farmfe.org/" target="_blank">
{/* <img src={FarmLogo} className="logo" alt="Farm logo" /> */}
<img src={FarmLogo} className="logo" alt="Farm logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"etag": "^1.8.1",
"http-proxy": "^1.18.1",
"react-refresh": "^0.14.0",
"sirv": "^2.0.3",
"sirv": "^2.0.4",
"ws": "^8.14.2"
},
"dependencies": {
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export async function resolveConfig(

// configPath may be file or directory
const { configFile, configPath: initialConfigPath } = inlineOptions;

const loadedUserConfig: any = await loadConfigFile(
configFile,
inlineOptions,
Expand Down Expand Up @@ -697,6 +698,7 @@ export function normalizePublicDir(root: string, publicDir = 'public') {
const absPublicDirPath = path.isAbsolute(publicDir)
? publicDir
: path.resolve(root, publicDir);

return absPublicDirPath;
}

Expand Down Expand Up @@ -915,6 +917,11 @@ export async function resolveUserConfig(
mode
};

resolvedUserConfig.publicDir = normalizePublicDir(
resolvedRootPath,
userConfig.publicDir
);

return resolvedUserConfig;
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export interface FarmCliOptions
logger?: Logger;
config?: string;
configFile?: string;
// todo: check to delete
configPath?: string;
compilation?: Config['config'];
mode?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ export async function start2(
);

const compiler = await createCompiler(resolvedUserConfig, logger);
const server = new newServer(compiler, resolvedUserConfig);
const server = new newServer(compiler, resolvedUserConfig, logger);
await server.createServer();
await server.listen();
// const devServer = await createDevServer(
Expand Down
22 changes: 10 additions & 12 deletions packages/core/src/newServer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Compiler } from '../compiler/index.js';
import { normalizePublicPath } from '../config/normalize-config/normalize-output.js';
import { NormalizedServerConfig, ResolvedUserConfig } from '../config/types.js';
import { logError } from '../server/error.js';
import { logger } from '../utils/logger.js';
import { Logger, logger } from '../utils/logger.js';
import { initPublicFiles } from '../utils/publicDir.js';
import { isObject } from '../utils/share.js';
import { FileWatcher } from '../watcher/index.js';
Expand Down Expand Up @@ -91,11 +91,16 @@ export class newServer {
publicPath?: string;
httpServer?: HttpServer;
watcher: FileWatcher;
logger: Logger;

constructor(compiler: CompilerType, config: ResolvedUserConfig) {
constructor(
compiler: CompilerType,
config: ResolvedUserConfig,
logger: Logger
) {
this.compiler = compiler;
this.config = config;

this.logger = logger;
if (!this.compiler) return;

this.publicPath =
Expand Down Expand Up @@ -132,15 +137,8 @@ export class newServer {
// middleware
// middlewares.use(compression());

if (this.publicDir) {
middlewares.use(
publicMiddleware(
this.httpServer,
this.compiler,
this.publicPath,
this.config
)
);
if (publicDir) {
middlewares.use(publicMiddleware(this.logger, this.config, publicFiles));
}
// TODO todo add appType
middlewares.use(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ResolvedUserConfig } from '../../config/types.js';
import { commonFsUtils } from '../../utils/fsUtils.js';
import { cleanUrl } from '../../utils/url.js';
import { HttpServer } from '../index.js';

export function htmlFallbackMiddleware(
server: HttpServer,
compiler: Compiler,
Expand Down
107 changes: 99 additions & 8 deletions packages/core/src/newServer/middlewares/publicMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,107 @@
import { Compiler } from '../../compiler/index.js';
import sirv from 'sirv';
import { ResolvedUserConfig } from '../../config/types.js';
import { HttpServer } from '../index.js';
import { colors } from '../../utils/color.js';
import { Logger } from '../../utils/logger.js';
import { removeHashFromPath, withTrailingSlash } from '../../utils/path.js';
import { normalizePath } from '../../utils/share.js';
import {
cleanUrl,
isImportRequest,
knownJavascriptExtensionRE,
removeImportQuery,
urlRE
} from '../../utils/url.js';

function warnAboutPublicDir(url: string, publicPath: string) {
let warning: string;
if (isImportRequest(url)) {
const rawUrl = removeImportQuery(url);
if (urlRE.test(url)) {
warning =
`Assets in the public directory are directly accessible at the root path.\n` +
`Use ${colors.brandColor(
rawUrl.replace(publicPath, '/')
)} instead of the explicit ${colors.brandColor(rawUrl)}.`;
} else {
warning =
'Assets in the public directory should not be imported directly in JavaScript.\n' +
`To import an asset, place it inside the src directory. Use ${colors.brandColor(
rawUrl.replace(publicPath, '/src/')
)} instead of ${colors.cyan(rawUrl)}.\n` +
`For referencing the asset's path, use ${colors.brandColor(
rawUrl.replace(publicPath, '/')
)}.`;
}
} else {
warning =
`Public directory files are accessible directly at the root path.\n` +
`Use ${colors.brandColor(
url.replace(publicPath, '/')
)} directly, rather than ${colors.brandColor(`${publicPath}${url}`)}.`;
}

return warning;
}

export function publicMiddleware(
server: HttpServer,
compiler: Compiler,
publicPath: string,
config: ResolvedUserConfig
logger: Logger,
config: ResolvedUserConfig,
publicFiles?: Set<string>
) {
return async function handlerPublicMiddleware(
const { publicDir, root } = config;
const publicPath = `${publicDir.slice(root.length)}`;
const headers = config.server.headers;
const serve = sirv(publicDir, {
dev: true,
etag: true,
extensions: [],
setHeaders: (res, path) => {
if (knownJavascriptExtensionRE.test(path)) {
res.setHeader('Content-Type', 'text/javascript');
}
if (headers) {
for (const name in headers) {
res.setHeader(name, headers[name]!);
}
}
}
});
const toFilePath = (url: string) => {
let filePath = cleanUrl(url);
if (filePath.indexOf('%') !== -1) {
try {
filePath = decodeURI(filePath);
} catch (err) {
// ignore
}
}
return normalizePath(filePath);
};

return async function farmHandlerPublicMiddleware(
req: any,
res: any,
next: () => void
) {};
) {
const url = removeHashFromPath(req.url!);
const filePath = toFilePath(url);

// If it is not equal, it means that it is recognized as a module
if (
publicDir.startsWith(withTrailingSlash(root)) &&
publicFiles.has(url) &&
req.url !== url
) {
const publicDirWarning = warnAboutPublicDir(url, publicPath);
if (publicDirWarning) {
logger.warn(publicDirWarning);
}
}

if (publicFiles && !publicFiles.has(filePath)) {
return next();
}

serve(req, res, next);
};
}
3 changes: 1 addition & 2 deletions packages/core/src/newServer/publicDir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ export async function initPublicFiles(
config: ResolvedUserConfig
): Promise<Set<string> | undefined> {
let fileNames: string[];
const publicDir: string = config.compilation?.assets?.publicDir as string;
console.log(publicDir);
const publicDir: string = config.publicDir;

try {
fileNames = await recursiveReaddir(publicDir);
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/utils/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ const postfixRE = /[?#].*$/;
export function stripQueryAndHash(path: string): string {
return path.replace(postfixRE, '');
}

export function removeHashFromPath(url: string): string {
const hashPattern = /(_[a-zA-Z\d]{4,8})\./;

const newURL = url.replace(hashPattern, '.');

return newURL;
}
13 changes: 13 additions & 0 deletions packages/core/src/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,16 @@ const postfixRE = /[?#].*$/;
export function cleanUrl(url: string): string {
return url.replace(postfixRE, '');
}

const importQueryRE = /(\?|&)import=?(?:&|$)/;
export const isImportRequest = (url: string): boolean =>
importQueryRE.test(url);

const trailingSeparatorRE = /[?&]$/;
export function removeImportQuery(url: string): string {
return url.replace(importQueryRE, '$1').replace(trailingSeparatorRE, '');
}

export const knownJavascriptExtensionRE = /\.[tj]sx?$/;

export const urlRE = /(\?|&)url(?:&|$)/;
Loading

0 comments on commit 69391da

Please sign in to comment.