如何配置实现ECMAScript同名文件夹文件的简化导入?
import Home from './Home' to ./Home/Home.js Instead of Index Files Absolutely! While NODE_PATH won’t fix this specific folder resolution quirk (it’s designed for adding global module search paths, not customizing how folder imports resolve), there are several straightforward ways to get the behavior you want. Here are the most practical approaches:
1. Use package.json's main or exports Field (No Build Tools Required)
This is the simplest, zero-config fix for individual folders:
- Inside your
Homefolder, create a tinypackage.jsonfile with just one line:
(Adjust the extension to match your file type—like{"main": "./Home.js"}.tsxfor React TypeScript files.) - Node.js, Webpack, Vite, and most other tools automatically respect this config. When you import
./Home, it’ll now resolve to./Home/Home.jsinstead of searching for an index file.
For ES Module-only projects (using type: module in your root package.json), the exports field is more standards-compliant:
{"exports": "./Home.js"}
2. Configure Your Bundler (Webpack, Vite, Etc.)
If you have multiple folders following this "folder-name matches file-name" pattern, setting up your bundler to handle this globally saves you from creating a package.json in every folder.
Example for Webpack:
Modify your webpack.config.js to add a custom resolver that checks for matching filenames in folders:
const path = require('path'); const fs = require('fs'); module.exports = { // ... other config resolve: { plugins: [ { apply(resolver) { resolver.hooks.resolve.tap('FolderSameNameResolver', (request) => { // Detect relative imports of folders (no file extension) const isFolderImport = !request.request.includes('.') && request.request.startsWith('./'); if (isFolderImport) { const folderName = path.basename(request.request); const targetPath = `${request.request}/${folderName}.js`; const fullPath = path.resolve(resolver.context, targetPath); // Use the target file if it exists if (fs.existsSync(fullPath)) { request.request = targetPath; } } return null; }); } } ] } };
Example for Vite:
Vite uses Rollup under the hood—add a custom alias rule in vite.config.js:
import { defineConfig } from 'vite'; import fs from 'fs'; import path from 'path'; export default defineConfig({ resolve: { alias: [ { find: /^\.\/([^/.]+)$/, replacement: (match, folderName) => { const targetPath = `./${folderName}/${folderName}.js`; if (fs.existsSync(path.resolve(__dirname, targetPath))) { return targetPath; } // Fall back to default if no matching file exists return match; } } ] } });
3. Use a Babel Plugin
If you’re using Babel, babel-plugin-module-resolver lets you define custom resolution rules that work across all bundlers (handled at transpilation time):
- Install the plugin:
npm install --save-dev babel-plugin-module-resolver - Add this to your
babel.config.js(or.babelrc):
const path = require('path'); const fs = require('fs'); module.exports = { plugins: [ ['module-resolver', { resolvePath: (sourcePath, currentFile) => { // Check for relative folder imports with no file extension if (sourcePath.startsWith('./') && !sourcePath.includes('.')) { const folderAbsolutePath = path.join(path.dirname(currentFile), sourcePath); const targetFileName = `${path.basename(sourcePath)}.js`; const targetAbsolutePath = path.join(folderAbsolutePath, targetFileName); // Resolve to the matching file if it exists if (fs.existsSync(targetAbsolutePath)) { return targetAbsolutePath; } } // Fall back to default resolution return sourcePath; } }] ] };
Quick Clarification on NODE_PATH
Just to clear this up: NODE_PATH tells Node where to look for bare imports (like import _ from 'lodash'), but it doesn’t alter how relative imports (like ./Home) resolve to files inside folders. So it won’t help with your specific use case.
内容的提问来源于stack exchange,提问作者Broda Noel

