diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index 2ce0e8e95fa1..5bc2f97e2b5b 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -107,12 +107,13 @@ jobs: steps: - uses: actions/checkout@v2 - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - - run: cat package.json | jq '.resolutions.webpack = "^5.0.0-beta.30"' > package.json.tmp && mv package.json.tmp package.json - - run: cat package.json | jq '.resolutions.react = "^17.0.0-rc.1"' > package.json.tmp && mv package.json.tmp package.json - - run: cat package.json | jq '.resolutions."react-dom" = "^17.0.0-rc.1"' > package.json.tmp && mv package.json.tmp package.json + - run: cat packages/next/package.json | jq '.resolutions.webpack = "^5.0.0-beta.30"' > package.json.tmp && mv package.json.tmp packages/next/package.json + - run: cat packages/next/package.json | jq '.resolutions.react = "^17.0.0-rc.1"' > package.json.tmp && mv package.json.tmp packages/next/package.json + - run: cat packages/next/package.json | jq '.resolutions."react-dom" = "^17.0.0-rc.1"' > package.json.tmp && mv package.json.tmp packages/next/package.json - run: yarn install --check-files - run: node run-tests.js test/integration/production/test/index.test.js - run: node run-tests.js test/integration/basic/test/index.test.js + - run: node run-tests.js test/integration/font-optimization/test/index.test.js - run: node run-tests.js test/acceptance/* testFirefox: diff --git a/examples/with-tailwindcss/tailwind.config.js b/examples/with-tailwindcss/tailwind.config.js index 544a211e989e..65167cc61c36 100644 --- a/examples/with-tailwindcss/tailwind.config.js +++ b/examples/with-tailwindcss/tailwind.config.js @@ -1,6 +1,7 @@ module.exports = { future: { removeDeprecatedGapUtilities: true, + purgeLayersByDefault: true, }, purge: ['./components/**/*.{js,ts,jsx,tsx}', './pages/**/*.{js,ts,jsx,tsx}'], theme: { diff --git a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts index 5b8517cf0cff..3a8763f97b54 100644 --- a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts +++ b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts @@ -5,8 +5,6 @@ import { getFontDefinitionFromNetwork, FontManifest, } from '../../../next-server/server/font-utils' -// @ts-ignore -import BasicEvaluatedExpression from 'webpack/lib/BasicEvaluatedExpression' import postcss from 'postcss' import minifier from 'cssnano-simple' import { OPTIMIZED_FONT_PROVIDERS } from '../../../next-server/lib/constants' @@ -16,6 +14,13 @@ const { RawSource } = webpack.sources || sources const isWebpack5 = parseInt(webpack.version!) === 5 +let BasicEvaluatedExpression: any +if (isWebpack5) { + BasicEvaluatedExpression = require('webpack/lib/javascript/BasicEvaluatedExpression') +} else { + BasicEvaluatedExpression = require('webpack/lib/BasicEvaluatedExpression') +} + async function minifyCss(css: string): Promise { return new Promise((resolve) => postcss([ @@ -62,13 +67,20 @@ export class FontStylesheetGatheringPlugin { if (parser?.state?.module?.resource.includes('node_modules')) { return } - return node.name === '__jsx' - ? new BasicEvaluatedExpression() - //@ts-ignore - .setRange(node.range) - .setExpression(node) - .setIdentifier('__jsx') - : undefined + let result + if (node.name === '__jsx') { + result = new BasicEvaluatedExpression() + // @ts-ignore + result.setRange(node.range) + result.setExpression(node) + result.setIdentifier('__jsx') + + // This was added webpack 5. + if (isWebpack5) { + result.getMembers = () => [] + } + } + return result }) parser.hooks.call diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index 22e926dd8c73..a7a4b069f7b2 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -92,7 +92,7 @@ if (process.env.__NEXT_i18n_SUPPORT) { const localePathResult = normalizeLocalePath(asPath, locales) if (localePathResult.detectedLocale) { - asPath = asPath.substr(localePathResult.detectedLocale.length + 1) + asPath = asPath.substr(localePathResult.detectedLocale.length + 1) || '/' } else { // derive the default locale if it wasn't detected in the asPath // since we don't prerender static pages with all possible default diff --git a/test/integration/i18n-support/test/index.test.js b/test/integration/i18n-support/test/index.test.js index a5d520ca9e07..098b12072997 100644 --- a/test/integration/i18n-support/test/index.test.js +++ b/test/integration/i18n-support/test/index.test.js @@ -29,6 +29,45 @@ let buildPagesDir const locales = ['en-US', 'nl-NL', 'nl-BE', 'nl', 'fr-BE', 'fr', 'en'] function runTests(isDev) { + it('should update asPath on the client correctly', async () => { + for (const check of ['en', 'En']) { + const browser = await webdriver(appPort, `/${check}`) + + expect(await browser.elementByCss('html').getAttribute('lang')).toBe('en') + expect(await browser.elementByCss('#router-locale').text()).toBe('en') + expect( + JSON.parse(await browser.elementByCss('#router-locales').text()) + ).toEqual(locales) + expect(await browser.elementByCss('#router-as-path').text()).toBe('/') + expect(await browser.elementByCss('#router-pathname').text()).toBe('/') + } + }) + + if (!isDev) { + it('should handle fallback correctly after generating', async () => { + const browser = await webdriver( + appPort, + '/en/gsp/fallback/hello-fallback' + ) + + // wait for the fallback to be generated/stored to ISR cache + browser.waitForElementByCss('#gsp') + + // now make sure we're serving the previously generated file from the cache + const html = await renderViaHTTP( + appPort, + '/en/gsp/fallback/hello-fallback' + ) + const $ = cheerio.load(html) + + expect($('#gsp').text()).toBe('gsp page') + expect($('#router-locale').text()).toBe('en') + expect(JSON.parse($('#router-locales').text())).toEqual(locales) + expect($('#router-pathname').text()).toBe('/gsp/fallback/[slug]') + expect($('#router-as-path').text()).toBe('/gsp/fallback/hello-fallback') + }) + } + it('should use correct default locale for locale domains', async () => { const res = await fetchViaHTTP(appPort, '/', undefined, { headers: {