diff --git a/lib/build/bundle.js b/lib/build/bundle.js index b8ef64c5..a08086a3 100644 --- a/lib/build/bundle.js +++ b/lib/build/bundle.js @@ -364,10 +364,7 @@ exports.Bundle = class { } let mapFileName = bundleFileName + '.map'; - let mapSourceRoot = path.posix.relative( - path.posix.join(process.cwd(), platform.output), - process.cwd() - ); + let mapSourceRoot = calculateRelativeSourceMapsRoot(process.cwd(), platform.output); logger.info(`Writing ${bundleFileName}...`); @@ -531,3 +528,20 @@ function uniqueBy(collection, key) { return seen.hasOwnProperty(k) ? false : (seen[k] = true); }); } + +/** + * Returns a POSIX-style relative path from `outputDir` back to `projectRoot`. + * Works on Windows, macOS and Linux. + * + * @param {string} projectRootDir - The root directory of the project. + * @param {string} outputDir - The output directory where the files are generated. + * @returns {string} A POSIX-style relative path from `outputDir` to `projectRoot`. + */ +function calculateRelativeSourceMapsRoot(projectRootDir, outputDir){ + const absoluteProjectRootDir = path.resolve(projectRootDir.split('\\').join('/')); + const absoluteOutputDir = path.resolve(absoluteProjectRootDir, outputDir.split('\\').join('/')); + + return path.relative(absoluteOutputDir, absoluteProjectRootDir).split('\\').join('/'); +} + +exports._calculateRelativeSourceMapsRoot = calculateRelativeSourceMapsRoot; diff --git a/spec/lib/build/bundle.spec.js b/spec/lib/build/bundle.spec.js index df972f42..9ea4288a 100644 --- a/spec/lib/build/bundle.spec.js +++ b/spec/lib/build/bundle.spec.js @@ -1,5 +1,6 @@ const BundlerMock = require('../../mocks/bundler'); const Bundle = require('../../../lib/build/bundle').Bundle; +const _calculateRelativeSourceMapsRoot = require('../../../lib/build/bundle')._calculateRelativeSourceMapsRoot; const CLIOptionsMock = require('../../mocks/cli-options'); const DependencyDescription = require('../../../lib/build/dependency-description').DependencyDescription; const SourceInclusion = require('../../../lib/build/source-inclusion').SourceInclusion; @@ -459,3 +460,45 @@ describe('the Bundle module', () => { }); }); }); + +describe('function _calculateRelativeSourceMapsRoot', () => { + const testCases = [ + // Basic UNIX cases + { projectDir: '/usr/home/my-app', outputDir: './dist', expected: '..' }, + { projectDir: '/usr/home/my-app/', outputDir: './dist/', expected: '..' }, + { projectDir: '/usr/home/my-app', outputDir: 'dist', expected: '..' }, + { projectDir: '/usr/home/my-app/', outputDir: 'dist/', expected: '..' }, + // Basic Windows cases + { projectDir: 'C:/My Documents/MyApp', outputDir: './dist', expected: '..' }, + { projectDir: 'C:/My Documents/MyApp/', outputDir: './dist/', expected: '..' }, + { projectDir: 'C:/My Documents/MyApp', outputDir: 'dist', expected: '..' }, + { projectDir: 'C:/My Documents/MyApp/', outputDir: 'dist/', expected: '..' }, + // Basic Windows cases with backslashes + { projectDir: 'C:\\My Documents\\MyApp', outputDir: '.\\dist', expected: '..' }, + { projectDir: 'C:\\My Documents\\MyApp\\', outputDir: '.\\dist\\', expected: '..' }, + { projectDir: 'C:\\My Documents\\MyApp', outputDir: 'dist', expected: '..' }, + { projectDir: 'C:\\My Documents\\MyApp\\', outputDir: 'dist\\', expected: '..' }, + // Windows mixed slashes + { projectDir: 'C:\\My Documents\\MyApp', outputDir: './dist', expected: '..' }, + { projectDir: 'C:\\My Documents\\MyApp\\', outputDir: './dist/', expected: '..' }, + { projectDir: 'C:/My Documents/MyApp/', outputDir: 'dist\\', expected: '..' }, + // Output directory outside of project root + { projectDir: '/usr/home/my-app', outputDir: '../wwwroot/scripts', expected: '../../my-app' }, + { projectDir: 'C:\\My Documents\\MyApp', outputDir: '../wwwroot/scripts', expected: '../../MyApp' }, + // Relative project root paths, basic cases + { projectDir: './my-app', outputDir: './dist', expected: '..' }, + { projectDir: 'my-app', outputDir: 'dist', expected: '..' }, + { projectDir: '.\\MyApp', outputDir: '.\\dist', expected: '..' }, + { projectDir: 'MyApp\\', outputDir: 'dist\\', expected: '..' }, + // Relative project root paths, output directory outside of project root + { projectDir: './my-app', outputDir: '../wwwroot/scripts', expected: '../../my-app' }, + { projectDir: '.\\MyApp\\', outputDir: '..\\wwwroot\\scripts\\', expected: '../../MyApp' } + ]; + + testCases.forEach(({ projectDir, outputDir, expected }) => { + it(`returns "${expected}" for projectDir "${projectDir}" and outputDir "${outputDir}"`, () => { + const result = _calculateRelativeSourceMapsRoot(projectDir, outputDir); + expect(result).toBe(expected); + }); + }); +});