This post explains how to use custom paths for efficient Module Resolution in large TypeScript projects.
A Primer of Modules
Looking at the State of the Octoverse 2020 you see that TypeScript has surged in popularity. TypeScript adds an unsound type system and powerful compiler to the JavaScript ecosystem.
Modules are not exclusive to TypeScript. They have been introduced with ECMAScript 2015 and TypeScript shares this concept.
Modules contain code that is executed within their own scope, not in the global scope. That means all variables, functions, classes, etc. that are declared in a module are not visible outside of the module unless they are explicitly exported using one of the export mechanisms. To consume the exported variable, function, class, interface, etc. it has to be imported using one of the import mechanisms.
The common mechanism today is the ES module: ECMAScript 2015, or ES6 module using the import/export
statements.
An example of a module is a React component that is shared between different pages. Extracting code into modules does not only make it easier to maintain a large code base and test functionality, but also to optimize your code. ES2015 allows to eliminate unused code via tree shaking.
# DefaultLayout.tsx
import React from 'react'
interface DefaultLayoutProps {
children: React.ReactNode
}
export const DefaultLayout = ({ children }: DefaultLayoutProps): JSX.Element => (
<div>{children}</div>
)
export default DefaultLayout
This component has a named export of DefaultLayout
and a default export.
Importing Modules
A typical folder structure for the React component π in a Next.js looks like this.
.
βββ src
β βββ components
β βββ layout
β βββ DefaultLayout.tsx
β βββ graphql
β βββ hocs
β βββ hooks
β βββ pages
β βββ state
β βββ theme
β βββ types
β βββ utils
To import this DefaultLayout
component in the DefaultLayout.tsx
the compiler needs to know where the module is located. Usually this is done by specifying a relative path to the component import DefaultLayout from '../../components/DefaultLayout
.
However, the TypeScript compiler can be instructed to use a different path to resolve the location of the module. This can be done via the tsconfig.json
file.
{
"compilerOptions": {
...
"paths": {
"@components/*": [
"./src/components/*"
],
"@theme/*": [
"./src/theme/*"
],
"@utils/*": [
"./src/utils/*"
],
"@hooks/*": [
"./src/hooks/*"
],
"@state/*": [
"./src/state/*"
],
"@pages/*": [
"./src/pages/*"
],
"@hocs/*": [
"./src/hocs/*"
],
"@type/*": [
"./src/types/*"
],
}
}
}
By adding these custom paths for the module resolution, modules the DefaultLayout
component can be imported with import DefaultLayout from '@components/layout/DefaultLayout'
.
import React from 'react'
import DefaultLayout from '@components/layout/DefaultLayout
const App = (): JSX.Element => <DefaultLayout />
export default App
β‘οΈ A great resource for writing React apps with TypeScript are the React TypeScript Cheatsheets
Top comments (0)