Skip to content

Commit

Permalink
fix(theme): use abs layout paths in theme loader (#365)
Browse files Browse the repository at this point in the history
  • Loading branch information
PeachScript committed Nov 8, 2020
1 parent 15a4590 commit 3090909
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v2
- uses: afc163/surge-preview@v1
env:
DUMI_THEME: dumi-theme-mobile
DUMI_THEME: ./packages/dumi-theme-mobile
with:
surge_token: ${{ secrets.SURGE_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"scripts": {
"dev": "cross-env BROWSER=none node ./packages/dumi/bin/dumi.js dev",
"dev:mobile": "cross-env BROWSER=none DUMI_THEME=dumi-theme-mobile node ./packages/dumi/bin/dumi.js dev",
"dev:mobile": "cross-env BROWSER=none DUMI_THEME=./packages/theme-mobile node ./packages/dumi/bin/dumi.js dev",
"watch": "npm run build -- --watch",
"doc:build": "cross-env BROWSER=none node ./packages/dumi/bin/dumi.js build",
"build": "father-build",
Expand Down
7 changes: 1 addition & 6 deletions packages/preset-dumi/src/routes/getRouteConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,7 @@ export default async (api: IApi, opts: IDumiOpts): Promise<IRoute[]> => {
// builtin outer layout
slash(path.relative(api.paths.absPagesPath, path.join(__dirname, '../theme/layout'))),
// theme layout
slash(
path.relative(
api.paths.absPagesPath,
path.resolve(paths.absNodeModulesPath, theme.layoutPaths._),
),
),
slash(path.relative(api.paths.absPagesPath, theme.layoutPaths._)),
],
// decorate standard umi routes
routes: decorateRoutes(childRoutes, opts, api),
Expand Down
64 changes: 38 additions & 26 deletions packages/preset-dumi/src/theme/loader.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import fs from 'fs';
import path from 'path';
import { winPath } from '@umijs/utils';
import { winPath, createDebug } from '@umijs/utils';
import { getModuleResolvePath } from '../utils/moduleResolver';
import ctx from '../context';

const debug = createDebug('dumi:theme');

interface ThemeComponent {
/**
* component name
Expand Down Expand Up @@ -81,26 +83,46 @@ function detectTheme() {
return localTheme ? [localTheme] : detectInstalledTheme();
}

/**
* get resolved path for theme module
* @param sourcePath
*/
function getThemeResolvePath(sourcePath: string) {
return getModuleResolvePath({
basePath: ctx.umi.cwd,
sourcePath,
silent: true,
// use empty alias to avoid dumi repo start failed
// because the auto-alias target theme-default/src
alias: {},
});
}

export default async () => {
if (!cache || process.env.NODE_ENV === 'test') {
const [name = process.env.DUMI_THEME || FALLBACK_THEME] = detectTheme();
const theme = path.isAbsolute(name) ? name : `${name}/src`;
const modulePath = winPath(path.resolve(ctx.umi.paths.absNodeModulesPath, theme));
const builtinPath = path.join(modulePath, 'builtins');
const [theme = process.env.DUMI_THEME || FALLBACK_THEME] = detectTheme();
const modulePath = path.isAbsolute(theme)
? theme
: // resolve real absolute path for theme package
winPath(path.dirname(getThemeResolvePath(theme)));
// local theme has no src directory but theme package has
const srcPath = path.isAbsolute(theme) ? theme : `${modulePath}/src`;
const builtinPath = winPath(path.join(srcPath, 'builtins'));
const components = fs.existsSync(builtinPath)
? fs
.readdirSync(builtinPath)
.filter(file => /\.(j|t)sx?$/.test(file))
.map(file => ({
identifier: path.parse(file).name,
source: winPath(path.join(theme, 'builtins', file)),
// still use module identifier rather than abs path for theme package modules
source: winPath(path.join(theme, builtinPath.replace(modulePath, ''), file)),
}))
: [];
const fallbacks = REQUIRED_THEME_BUILTINS.reduce((result, name) => {
if (components.every(({ identifier }) => identifier !== name)) {
const fallbacks = REQUIRED_THEME_BUILTINS.reduce((result, bName) => {
if (components.every(({ identifier }) => identifier !== bName)) {
result.push({
identifier: name,
source: winPath(path.join(FALLBACK_THEME, 'src', 'builtins', `${name}`)),
identifier: bName,
source: winPath(path.join(FALLBACK_THEME, 'src', 'builtins', `${bName}`)),
});
}

Expand All @@ -109,36 +131,24 @@ export default async () => {
const layoutPaths = {} as IThemeLoadResult['layoutPaths'];

// outer layout: layout.tsx or layouts/index.tsx
[winPath(path.join(theme, 'layout')), winPath(path.join(theme, 'layouts'))].some(
[winPath(path.join(srcPath, 'layout')), winPath(path.join(srcPath, 'layouts'))].some(
(layoutPath, i, outerLayoutPaths) => {
try {
getModuleResolvePath({
basePath: ctx.umi.paths.cwd,
sourcePath: layoutPath,
silent: true,
});

layoutPaths._ = layoutPath;
layoutPaths._ = getThemeResolvePath(layoutPath);

return true;
} catch (err) {
// fallback to default theme layout if cannot find any valid layout
if (i === outerLayoutPaths.length - 1) {
layoutPaths._ = winPath(path.join(FALLBACK_THEME, 'src', 'layout'));
layoutPaths._ = getThemeResolvePath(path.join(FALLBACK_THEME, 'src', 'layout'));
}
}
},
);

// demo layout
try {
layoutPaths.demo = winPath(path.join(theme, 'layouts', 'demo'));

getModuleResolvePath({
basePath: ctx.umi.paths.cwd,
sourcePath: layoutPaths.demo,
silent: true,
});
layoutPaths.demo = getThemeResolvePath(path.join(srcPath, 'layouts', 'demo'));
} catch (err) {
layoutPaths.demo = null;
}
Expand All @@ -154,6 +164,8 @@ export default async () => {
layoutPaths,
},
});

debug(cache);
}

return cache;
Expand Down
4 changes: 3 additions & 1 deletion packages/preset-dumi/src/utils/moduleResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface IModuleResolverOpts {
sourcePath: string;
extensions?: string[];
silent?: boolean;
alias?: { [key: string]: string };
}

const getResolveAlias = (() => {
Expand Down Expand Up @@ -42,12 +43,13 @@ export const getModuleResolvePath = ({
sourcePath,
extensions = DEFAULT_EXT,
silent,
alias,
}: IModuleResolverOpts) => {
try {
return slash(
resolve.create.sync({
extensions,
alias: getResolveAlias(),
alias: alias || getResolveAlias(),
symlinks: false,
mainFiles: ['index', 'package.json'],
})(fs.statSync(basePath).isDirectory() ? basePath : path.parse(basePath).dir, sourcePath),
Expand Down

0 comments on commit 3090909

Please sign in to comment.