rsnext/test/development/basic-basepath/next-dynamic.test.ts

248 lines
7.8 KiB
TypeScript
Raw Normal View History

import { join } from 'path'
import cheerio from 'cheerio'
import webdriver from 'next-webdriver'
import { createNext, FileRef } from 'e2e-utils'
import { renderViaHTTP, check } from 'next-test-utils'
import { NextInstance } from 'test/lib/next-modes/base'
describe('basic next/dynamic usage', () => {
let next: NextInstance
beforeAll(async () => {
next = await createNext({
files: {
components: new FileRef(join(__dirname, 'next-dynamic/components')),
pages: new FileRef(join(__dirname, 'next-dynamic/pages')),
},
nextConfig: {
basePath: '/docs',
},
})
})
afterAll(() => next.destroy())
async function get$(path, query?: any) {
const html = await renderViaHTTP(next.appPort, path, query)
return cheerio.load(html)
}
describe('Dynamic import', () => {
describe('default behavior', () => {
Universal Webpack (#3578) * Speed up next build * Document webpack config * Speed up next build * Remove comment * Add comment * Clean up rules * Add comments * Run in parallel * Push plugins seperately * Create a new chunk for react * Don’t uglify react since it’s already uglified. Move react to commons in development * Use the minified version directly * Re-add globpattern * Move loaders into a separate variable * Add comment linking to Dan’s explanation * Remove dot * Add universal webpack * Initial dev support * Fix linting * Add changes from Arunoda's work * Made next dev works. But super slow and no HMR support. * Fix client side hot reload * Server side hmr * Only in dev * Add on-demand-entries client + hot-middleware * Add .babelrc support * Speed up on demand entries by running in parallel * Serve static generated files * Add missing config in dev * Add sass support * Add support for .map * Add cssloader config and fix .jsx support * Rename * use same defaults as css-loader. Fix linting * Add NoEmitErrorsPlugin * Add clientBootstrap * Use webpackhotmiddleware on the multi compiler * alpha.3 * Use babel 16.2.x * Fix reloading after error * Remove comment * Release 5.0.0-univeral-alpha.1 * Remove check for React 16 * Release 5.0.0-universal-alpha.2 * React hot loader v4 * Use our static file rendering machanism to serve pages. This should work well since the file path for a page is predictable. * Release 5.0.0-universal-alpha.3 * Remove optional loaders * Release 5.0.0-universal-alpha.4 * Remove clientBootstrap * Remove renderScript * Make sure pages bundles are served correctly * Remove unused import * Revert to using the same code as canary * Fix hot loader * Release 5.0.0-universal-alpha.5 * Check if externals dir exist before applying config * Add typescript support * Add support for transpiling certain packages in node_modules Thanks to @giuseppeg’s work in https://github.com/zeit/next.js/pull/3319 * Add BABEL_DISABLE_CACHE support * Make sourcemaps in production opt-in * Revert "Add support for transpiling certain packages in node_modules" This reverts commit d4b1d9babfb4b9ed4f4b12d56d52dee233e862da. In favor of a better api around this. * Support typescript through next.config.js * Remove comments * Bring back commons.js calculation * Remove unused dependencies * Move base.config.js to webpack.js * Make sure to only invalidate webpackDevMiddleware one after other. * Allow babel-loder caching by default. * Add comment about preact support * Bring back buildir replace * Remove obsolete plugin * Remove build replace, speed up build * Resolve page entries like pages/day/index.js to pages/day.js * Add componentDidCatch back * Compile to bundles * Use config.distDir everywhere * Make sure the file is an array * Remove console.log * Apply optimization to uglifyjs * Add comment pointing to source * Create entries the same way in dev and production * Remove unused and broken pagesGlobPattern * day/index.js is automatically turned into day.js at build time * Remove poweredByHeader option * Load pages with the correct path. * Release 5.0.0-universal-alpha.6 * Make sure react-dom/server can be overwritten by module-alias * Only add react-hot-loader babel plugin in dev * Release 5.0.0-universal-alpha.7 * Revert tests * Release 5.0.0-universal-alpha.10 * Make sure next/head is working properly. * Add wepack alias for 'next' back. * Make sure overriding className in next/head works * Alias react too * Add missing r * Fragment fallback has to wrap the children * Use min.js * Remove css.js * Remove wallaby.js * Release 5.0.0-universal-alpha.11 * Resolve relative to workdir instead of next * Make sure we touch the right file * Resolve next modules * Remove dotjsx removal plugins since we use webpack on the server * Revert "Resolve relative to workdir instead of next" This reverts commit a13f3e4ab565df9e2c9a3dfc8eb4009c0c2e02ed. * Externalize any locally loaded module lives outside of app dir. * Remove server aliases * Check node_modules reliably * Add symlink to next for tests * Make sure dynamic imports work locally. This is why we need it: https://github.com/webpack/webpack/blob/b545b519b2024e3f8be3041385bd326bf5d24449/lib/MainTemplate.js#L68 We need to have the finally clause in the above in __webpack_require__. webpack output option strictModuleExceptionHandling does that. * dynmaic -> dynamic * Remove webpack-node-externals * Make sure dynamic imports support SSR. * Remove css support in favor of next-css * Make sure we load path from `/` since it’s included in the path matching * Catch when ensurepage couldn’t be fulfilled for `.js.map` * Register require cache flusher for both client and server * Add comment explaining this is to facilitate hot reloading * Only load module when needed * Remove unused modules * Release 5.0.0-universal-alpha.12 * Only log the `found babel` message once * Make sure ondemand entries working correctly. Now we are just using a single instance of OnDemandEntryHandler. * Better sourcemaps * Release 5.0.0-universal-alpha.13 * Lock uglify version to 1.1.6 * Release 5.0.0-universal-alpha.14 * Fix a typo. * Introduce multi-zones support for mircofrontends * Add section on css
2018-01-30 16:40:52 +01:00
it('should render dynamic import components', async () => {
const $ = await get$('/docs/dynamic/ssr')
// Make sure the client side knows it has to wait for the bundle
expect(JSON.parse($('#__NEXT_DATA__').html()).dynamicIds).toContain(
'dynamic/ssr.js -> ../../components/hello1'
)
expect($('body').text()).toMatch(/Hello World 1/)
})
it('should render dynamic import components using a function as first parameter', async () => {
const $ = await get$('/docs/dynamic/function')
// Make sure the client side knows it has to wait for the bundle
expect(JSON.parse($('#__NEXT_DATA__').html()).dynamicIds).toContain(
'dynamic/function.js -> ../../components/hello1'
)
expect($('body').text()).toMatch(/Hello World 1/)
})
it('should render even there are no physical chunk exists', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/docs/dynamic/no-chunk')
await check(
() => browser.elementByCss('body').text(),
/Welcome, normal/
)
await check(
() => browser.elementByCss('body').text(),
/Welcome, dynamic/
)
} finally {
if (browser) {
await browser.close()
}
}
})
it('should hydrate nested chunks', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/docs/dynamic/nested')
await check(() => browser.elementByCss('body').text(), /Nested 1/)
await check(() => browser.elementByCss('body').text(), /Nested 2/)
await check(
() => browser.elementByCss('body').text(),
/Browser hydrated/
)
if ((global as any).browserName === 'chrome') {
const logs = await browser.log('browser')
2020-05-18 21:24:37 +02:00
logs.forEach((logItem) => {
expect(logItem.message).not.toMatch(
/Expected server HTML to contain/
)
})
}
} finally {
if (browser) {
await browser.close()
}
}
})
it('should render the component Head content', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/docs/dynamic/head')
await check(() => browser.elementByCss('body').text(), /test/)
const backgroundColor = await browser
.elementByCss('.dynamic-style')
.getComputedCss('background-color')
const height = await browser
.elementByCss('.dynamic-style')
.getComputedCss('height')
expect(height).toBe('200px')
expect(backgroundColor).toMatch(/rgba?\(0, 128, 0/)
} finally {
if (browser) {
await browser.close()
}
}
})
})
describe('ssr:false option', () => {
it('should not render loading on the server side', async () => {
const $ = await get$('/docs/dynamic/no-ssr')
expect($('body').html()).not.toContain('"dynamicIds"')
expect($('body').text()).not.toMatch('loading...')
})
it('should render the component on client side', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/docs/dynamic/no-ssr')
await check(
() => browser.elementByCss('body').text(),
/Hello World 1/
)
} finally {
if (browser) {
await browser.close()
}
}
})
})
describe('ssr:true option', () => {
it('Should render the component on the server side', async () => {
const $ = await get$('/docs/dynamic/ssr-true')
expect($('body').html()).toContain('"dynamicIds"')
expect($('p').text()).toBe('Hello World 1')
})
it('should render the component on client side', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/docs/dynamic/ssr-true')
await check(
() => browser.elementByCss('body').text(),
/Hello World 1/
)
} finally {
if (browser) {
await browser.close()
}
}
})
})
describe('custom chunkfilename', () => {
it('should render the correct filename', async () => {
const $ = await get$('/docs/dynamic/chunkfilename')
expect($('body').text()).toMatch(/test chunkfilename/)
expect($('html').html()).toMatch(/hello-world\.js/)
})
it('should render the component on client side', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/docs/dynamic/chunkfilename')
await check(
() => browser.elementByCss('body').text(),
/test chunkfilename/
)
} finally {
if (browser) {
await browser.close()
}
}
})
})
describe('custom loading', () => {
it('should render custom loading on the server side when `ssr:false` and `loading` is provided', async () => {
const $ = await get$('/docs/dynamic/no-ssr-custom-loading')
expect($('p').text()).toBe('LOADING')
})
it('should render the component on client side', async () => {
let browser
try {
browser = await webdriver(
next.appPort,
'/docs/dynamic/no-ssr-custom-loading'
)
await check(
() => browser.elementByCss('body').text(),
/Hello World 1/
)
} finally {
if (browser) {
await browser.close()
}
}
})
})
describe('Multiple modules', () => {
it('should only include the rendered module script tag', async () => {
const $ = await get$('/docs/dynamic/multiple-modules')
const html = $('html').html()
expect(html).toMatch(/hello1\.js/)
expect(html).not.toMatch(/hello2\.js/)
})
it('should only load the rendered module in the browser', async () => {
let browser
try {
browser = await webdriver(
next.appPort,
'/docs/dynamic/multiple-modules'
)
const html = await browser.eval('document.documentElement.innerHTML')
expect(html).toMatch(/hello1\.js/)
expect(html).not.toMatch(/hello2\.js/)
} finally {
if (browser) {
await browser.close()
}
}
})
it('should only render one bundle if component is used multiple times', async () => {
const $ = await get$('/docs/dynamic/multiple-modules')
const html = $('html').html()
try {
expect(html.match(/chunks[\\/]hello1\.js/g).length).toBe(1)
expect(html).not.toMatch(/hello2\.js/)
} catch (err) {
console.error(html)
throw err
}
})
})
})
})