From 969d6e805bf66a8940094d3d4fe6a991274155a6 Mon Sep 17 00:00:00 2001 From: Wesley Luyten Date: Fri, 2 Feb 2024 09:45:05 -0600 Subject: [PATCH] fix: import next.config.js in Windows (#159) * chore: add windows ci test * fix: dynamic import file path in Windows * fix: try forward slashes * chore: log out file path * fix: pathToFileURL().href related issue https://github.com/nodejs/node/issues/34765 * chore: log out error * fix: try adding cwd() * fix: cross platform write file script related https://github.com/shelljs/shx/issues/192 * fix: try next-video/process import * fix: cross platform glob expansion * chore: use codecov v4 * chore: move next.config.js mock test file --- .github/workflows/ci.yml | 9 ++++----- package.json | 8 ++++---- src/config.ts | 17 +++++++++++++---- tests/cli/sync.test.ts | 14 ++++++++------ tests/config.test.ts | 22 ++++++++++++++++++++++ tests/next.config.js | 7 +++++++ 6 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 tests/config.test.ts create mode 100644 tests/next.config.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e958bb..12a5fda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,12 +12,11 @@ env: jobs: build: - runs-on: ubuntu-latest - strategy: matrix: - node-version: [18.x, 20.x] - + os: [ubuntu-latest, windows-latest] + node-version: [18, 20] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} @@ -29,6 +28,6 @@ jobs: - run: npm test - run: npm run coverage - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/package.json b/package.json index 1fcdfad..b537cf9 100644 --- a/package.json +++ b/package.json @@ -48,12 +48,12 @@ "types:cjs": "tsc --outDir dist/cjs", "prebuild": "npm run clean && npm run types", "build": "npm run build:esm && npm run build:cjs", - "build:esm": "esbuild src/*.ts* src/*/*.ts* src/*/*/*.ts* --outdir=dist --format=esm --target=es2020", - "build:cjs": "esbuild src/*.ts* src/*/*.ts* src/*/*/*.ts* --outdir=dist/cjs --platform=node --format=cjs --target=es2020 --define:import.meta.url=\\\"\\\"", - "postbuild:cjs": "echo '{\"type\": \"commonjs\"}' > ./dist/cjs/package.json", + "build:esm": "esbuild \"src/**/*.ts*\" --outdir=dist --format=esm --target=es2020", + "build:cjs": "esbuild \"src/**/*.ts*\" --outdir=dist/cjs --platform=node --format=cjs --target=es2020 --define:import.meta.url=\\\"\\\"", + "postbuild:cjs": "node --eval \"fs.writeFileSync('./dist/cjs/package.json', '{\\\"type\\\": \\\"commonjs\\\"}')\"", "prepare": "npm run build", "cli": "node --loader tsx --no-warnings ./src/cli", - "test": "glob -c \"c8 --src src --exclude 'tests/**' node --loader tsx --no-warnings --test\" \"./tests/**/*.test.{ts,tsx}\"", + "test": "glob -c \"c8 --src src --exclude 'next.config.js' --exclude 'tests/**' --exclude 'dist/**' node --loader tsx --no-warnings --test\" \"./tests/**/*.test.{ts,tsx}\"", "coverage": "c8 report --reporter=text-lcov > ./coverage/lcov.info" }, "peerDependencies": { diff --git a/src/config.ts b/src/config.ts index 7f69d71..05d33dc 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,6 @@ -import { env } from 'node:process'; +import { env, cwd } from 'node:process'; import path from 'node:path'; +import { pathToFileURL } from 'node:url'; /** * Video configurations @@ -48,10 +49,12 @@ export async function getVideoConfig(): Promise { // Import the app's next.config.(m)js file so the env variable // __NEXT_VIDEO_OPTS set in with-next-video.ts can be used. try { - await import(/* webpackIgnore: true */ path.resolve('next.config.js')); - } catch { + await importConfig('next.config.js'); + } catch (err) { + console.error(err); + try { - await import(/* webpackIgnore: true */ path.resolve('next.config.mjs')); + await importConfig('next.config.mjs'); } catch { console.error('Failed to load next.config.js or next.config.mjs'); } @@ -59,3 +62,9 @@ export async function getVideoConfig(): Promise { } return JSON.parse(env['__NEXT_VIDEO_OPTS'] ?? '{}'); } + +async function importConfig(file: string) { + const absFilePath = path.resolve(cwd(), file); + const fileUrl = pathToFileURL(absFilePath).href; + return import(/* webpackIgnore: true */ fileUrl); +} diff --git a/tests/cli/sync.test.ts b/tests/cli/sync.test.ts index 8b9131f..dd51431 100644 --- a/tests/cli/sync.test.ts +++ b/tests/cli/sync.test.ts @@ -55,14 +55,14 @@ describe('cli', () => { async function createTempDir(): Promise { // Create a temporary directory and populate it with some files. - const dir = await fs.mkdtemp(path.join('tests', 'tmp-videos-')); - + const dir = await fs.mkdtemp('tmp-videos-'); tmpDirs.push(dir); - return dir; } before(() => { + process.chdir('tests'); + process.env.MUX_TOKEN_ID = 'fake-token-id'; process.env.MUX_TOKEN_SECRET = 'fake-token-secret'; @@ -79,12 +79,14 @@ describe('cli', () => { }); }); - after(() => { + after(async () => { server.close(); - tmpDirs.forEach(async (dir) => { + for (const dir of tmpDirs) { await fs.rm(dir, { recursive: true, force: true }); - }); + } + + process.chdir('../'); }); describe('sync', () => { diff --git a/tests/config.test.ts b/tests/config.test.ts new file mode 100644 index 0000000..2cfb2cd --- /dev/null +++ b/tests/config.test.ts @@ -0,0 +1,22 @@ +import assert from 'node:assert'; +import { describe, it, before, after } from 'node:test'; +import { getVideoConfig } from '../src/config.js'; + +describe('config', () => { + before(() => { + process.chdir('tests'); + }); + + after(() => { + process.chdir('../'); + }); + + it('getVideoConfig', async () => { + // Test that the default config is returned if no next.config.js file is found. + const videoConfig = await getVideoConfig(); + assert.equal(videoConfig.folder, 'videos'); + assert.equal(videoConfig.path, '/api/video'); + assert.equal(videoConfig.provider, 'mux'); + assert.deepStrictEqual(videoConfig.providerConfig, {}); + }); +}); diff --git a/tests/next.config.js b/tests/next.config.js new file mode 100644 index 0000000..c191c8b --- /dev/null +++ b/tests/next.config.js @@ -0,0 +1,7 @@ +// This file is used in the tests to mock the next.config.js file!!! +import { withNextVideo } from 'next-video/process'; + +/** @type {import('next').NextConfig} */ +const nextConfig = {}; + +export default withNextVideo(nextConfig);