Skip to content

Commit

Permalink
Add support for baseUrl option in tsconfig and jsconfig (#11203)
Browse files Browse the repository at this point in the history
* Add support for baseUrl option in tsconfig and jsconfig

* Move jsconfigPath

* Remove filter
  • Loading branch information
timneutkens committed Mar 19, 2020
1 parent f0c6df4 commit 38e42cd
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/next/build/webpack-config.ts
Expand Up @@ -217,6 +217,22 @@ export default async function getBaseWebpackConfig(
? config.typescript?.ignoreDevErrors
: config.typescript?.ignoreBuildErrors

let jsConfig
// jsconfig is a subset of tsconfig
if (useTypeScript) {
jsConfig = require(tsConfigPath)
}

const jsConfigPath = path.join(dir, 'jsconfig.json')
if (!useTypeScript && (await fileExists(jsConfigPath))) {
jsConfig = require(jsConfigPath)
}

let resolvedBaseUrl
if (jsConfig?.compilerOptions?.baseUrl) {
resolvedBaseUrl = path.resolve(dir, jsConfig.compilerOptions.baseUrl)
}

const resolveConfig = {
// Disable .mjs for node_modules bundling
extensions: isServer
Expand Down Expand Up @@ -889,6 +905,11 @@ export default async function getBaseWebpackConfig(
].filter((Boolean as any) as ExcludesFalse),
}

// Support tsconfig and jsconfig baseUrl
if (resolvedBaseUrl) {
webpackConfig.resolve?.modules?.push(resolvedBaseUrl)
}

webpackConfig = await buildConfiguration(webpackConfig, {
rootDirectory: dir,
customAppFile,
Expand Down
5 changes: 5 additions & 0 deletions test/integration/jsconfig-baseurl/components/world.js
@@ -0,0 +1,5 @@
import React from 'react'

export function World() {
return <>World</>
}
5 changes: 5 additions & 0 deletions test/integration/jsconfig-baseurl/jsconfig.json
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"baseUrl": "."
}
}
6 changes: 6 additions & 0 deletions test/integration/jsconfig-baseurl/next.config.js
@@ -0,0 +1,6 @@
module.exports = {
onDemandEntries: {
// Make sure entries are not getting disposed.
maxInactiveAge: 1000 * 60 * 60,
},
}
9 changes: 9 additions & 0 deletions test/integration/jsconfig-baseurl/pages/hello.js
@@ -0,0 +1,9 @@
import React from 'react'
import { World } from 'components/world'
export default function HelloPage() {
return (
<div>
<World />
</div>
)
}
31 changes: 31 additions & 0 deletions test/integration/jsconfig-baseurl/test/index.test.js
@@ -0,0 +1,31 @@
/* eslint-env jest */
/* global jasmine */
import { join } from 'path'
import cheerio from 'cheerio'
import { renderViaHTTP, findPort, launchApp, killApp } from 'next-test-utils'

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 2

const appDir = join(__dirname, '..')
let appPort
let app

async function get$(path, query) {
const html = await renderViaHTTP(appPort, path, query)
return cheerio.load(html)
}

describe('TypeScript Features', () => {
describe('default behavior', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort, {})
})
afterAll(() => killApp(app))

it('should render the page', async () => {
const $ = await get$('/hello')
expect($('body').text()).toMatch(/World/)
})
})
})
5 changes: 5 additions & 0 deletions test/integration/typescript-baseurl/components/world.tsx
@@ -0,0 +1,5 @@
import React from 'react'

export function World(): JSX.Element {
return <>World</>
}
6 changes: 6 additions & 0 deletions test/integration/typescript-baseurl/next.config.js
@@ -0,0 +1,6 @@
module.exports = {
onDemandEntries: {
// Make sure entries are not getting disposed.
maxInactiveAge: 1000 * 60 * 60,
},
}
9 changes: 9 additions & 0 deletions test/integration/typescript-baseurl/pages/hello.tsx
@@ -0,0 +1,9 @@
import React from 'react'
import { World } from 'components/world'
export default function HelloPage(): JSX.Element {
return (
<div>
<World />
</div>
)
}
31 changes: 31 additions & 0 deletions test/integration/typescript-baseurl/test/index.test.js
@@ -0,0 +1,31 @@
/* eslint-env jest */
/* global jasmine */
import { join } from 'path'
import cheerio from 'cheerio'
import { renderViaHTTP, findPort, launchApp, killApp } from 'next-test-utils'

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 2

const appDir = join(__dirname, '..')
let appPort
let app

async function get$(path, query) {
const html = await renderViaHTTP(appPort, path, query)
return cheerio.load(html)
}

describe('TypeScript Features', () => {
describe('default behavior', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort, {})
})
afterAll(() => killApp(app))

it('should render the page', async () => {
const $ = await get$('/hello')
expect($('body').text()).toMatch(/World/)
})
})
})
20 changes: 20 additions & 0 deletions test/integration/typescript-baseurl/tsconfig.json
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"baseUrl": ".",
"esModuleInterop": true,
"module": "esnext",
"jsx": "preserve",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "components", "pages"]
}

0 comments on commit 38e42cd

Please sign in to comment.