Skip to content

Commit

Permalink
feat: force sourceMap: true on all typescript projects (cypress-io/cy…
Browse files Browse the repository at this point in the history
  • Loading branch information
brian-mann authored May 18, 2020
1 parent 7f964ff commit 1afdc0a
Show file tree
Hide file tree
Showing 10 changed files with 292 additions and 10 deletions.
1 change: 1 addition & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"./test/_test-output",
"node_modules"
],
"require": "ts-node/register",
"exit": true
}
1 change: 1 addition & 0 deletions examples/use-ts-loader/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"sourceMap": true,
"outDir": "./dist/",
"noImplicitAny": true,
"module": "commonJS",
Expand Down
7 changes: 7 additions & 0 deletions import-sorter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"generalConfiguration": {
"exclude": [
"index.ts"
]
}
}
20 changes: 16 additions & 4 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { overrideSourceMaps } from './lib/typescript-overrides'

import * as Promise from 'bluebird'
import * as events from 'events'
import * as _ from 'lodash'
Expand Down Expand Up @@ -95,7 +97,7 @@ interface WebpackPreprocessor extends WebpackPreprocessorFn {
*/
// @ts-ignore
const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): FilePreprocessor => {
debug('user options:', options)
debug('user options: %o', options)

// we return function that accepts the arguments provided by
// the event 'file:preprocessor'
Expand Down Expand Up @@ -151,11 +153,21 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F
},
})
.tap((opts) => {
if (opts.devtool !== false) {
debug('setting devtool to inline-source-map')
if (opts.devtool === false) {
// disable any overrides if
// we've explictly turned off sourcemaps
overrideSourceMaps(false)

opts.devtool = 'inline-source-map'
return
}

debug('setting devtool to inline-source-map')

opts.devtool = 'inline-source-map'

// override typescript to always generate
// proper source maps
overrideSourceMaps(true)
})
.value() as any

Expand Down
54 changes: 54 additions & 0 deletions lib/typescript-overrides.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const debug = require('debug')('cypress:webpack')

let sourceMapOverride: null | boolean = null

export const tryRequireTypescript = () => {
try {
// reset each time this is called
sourceMapOverride = null

const typescript = require('typescript')

debug('typescript found, overriding typescript.createProgram()')

const { createProgram } = typescript

typescript.createProgram = (...args: [any]) => {
const [programOptions] = args
const { options } = programOptions

debug('typescript unmodified createProgram options %o', options)

// if sourceMap has been set then apply
// these overrides to force typescript
// to generate the right sourcemaps
if (sourceMapOverride !== null) {
options.sourceMap = sourceMapOverride

delete options.inlineSources
delete options.inlineSourceMap

debug('typescript modified createProgram options %o', options)
}

return createProgram.apply(typescript, args)
}

return typescript
} catch (err) {
debug('typescript not found')

// for testing
return err
}
}

export const overrideSourceMaps = (val: boolean) => {
sourceMapOverride = val
}

export const getSourceMapOverride = () => {
return sourceMapOverride
}

tryRequireTypescript()
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"main": "dist",
"scripts": {
"ban": "ban",
"build": "tsc",
"build": "rm -rf dist && tsc",
"deps": "deps-ok && dependency-check --no-dev .",
"license": "license-checker --production --onlyunknown --csv",
"lint": "eslint --ext .js,.jsx,.json,.ts,.tsx .",
Expand All @@ -17,9 +17,9 @@
"pretest": "yarn lint && yarn build",
"test": "yarn test-unit && yarn test-e2e",
"test-debug": "node --inspect --debug-brk ./node_modules/.bin/_mocha",
"test-e2e": "mocha test/e2e/*.spec.js",
"test-unit": "mocha test/unit/*.spec.js",
"test-watch": "yarn test-unit & chokidar '*.js' 'test/unit/*.js' -c 'yarn test-unit'",
"test-e2e": "mocha test/e2e/*.spec.*",
"test-unit": "mocha test/unit/*.spec.*",
"test-watch": "yarn test-unit & chokidar '**/*.(js|ts)' 'test/unit/*.(js|ts)' -c 'yarn test-unit'",
"types": "tsc --noEmit"
},
"husky": {
Expand Down Expand Up @@ -61,6 +61,7 @@
"mocha": "^7.1.0",
"mockery": "2.1.0",
"prettier-eslint-cli": "4.4.0",
"proxyquire": "2.1.3",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-scripts": "3.2",
Expand All @@ -69,6 +70,7 @@
"sinon-chai": "^3.5.0",
"snap-shot-it": "7.9.2",
"start-server-and-test": "1.10.11",
"ts-node": "8.10.1",
"typescript": "3.8.3",
"webpack": "^4.18.1"
},
Expand Down
9 changes: 9 additions & 0 deletions test/unit/dist.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const { expect } = require('chai')
const preprocessor = require('../../dist/index')

describe('tyepscript ./dist output', () => {
it('builds dist correctly', () => {
expect(preprocessor).to.be.a('function')
expect(preprocessor).to.have.property('defaultOptions')
})
})
9 changes: 8 additions & 1 deletion test/unit/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ mockery.enable({

mockery.registerMock('webpack', webpack)

const preprocessor = require('../../dist/index')
const preprocessor = require('../../index')
const { getSourceMapOverride } = require('../../lib/typescript-overrides')

describe('webpack preprocessor', function () {
beforeEach(function () {
Expand Down Expand Up @@ -155,6 +156,8 @@ describe('webpack preprocessor', function () {
expect(webpack).to.be.calledWithMatch({
devtool: 'inline-source-map',
})

expect(getSourceMapOverride()).to.be.true
})
})

Expand All @@ -165,6 +168,8 @@ describe('webpack preprocessor', function () {
expect(webpack).to.be.calledWithMatch({
devtool: false,
})

expect(getSourceMapOverride()).to.be.false
})
})

Expand All @@ -175,6 +180,8 @@ describe('webpack preprocessor', function () {
expect(webpack).to.be.calledWithMatch({
devtool: 'inline-source-map',
})

expect(getSourceMapOverride()).to.be.true
})
})
})
Expand Down
121 changes: 121 additions & 0 deletions test/unit/typescript-overrides.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
const { expect } = require('chai')
const sinon = require('sinon')
const proxyquire = require('proxyquire').noPreserveCache()

type Typescript = {
createProgram: sinon.SinonStub
}

let typescript: Typescript
let createProgram: Typescript['createProgram']

import '../../lib/typescript-overrides'

describe('./lib/typescript-overrides', () => {
beforeEach(() => {
createProgram = sinon.stub()
typescript = {
createProgram,
}
})

context('.getSourceMapOverride', () => {
it('is null by default', () => {
const typescriptOverrides = proxyquire('../../lib/typescript-overrides', {
typescript,
})

expect(typescriptOverrides.getSourceMapOverride()).to.be.null
})
})

context('.tryRequireTypescript', () => {
it('gracefully returns error when typescript cannot be required', () => {
const typescriptOverrides = proxyquire('../../lib/typescript-overrides', {
typescript: null,
})

const err = typescriptOverrides.tryRequireTypescript()

expect(err).to.be.instanceOf(Error)
expect(err.message).to.eq(`Cannot find module 'typescript'`)
})
})

context('.overrideSourceMaps', () => {
it('it sets sourceMap: true', () => {
const typescriptOverrides = proxyquire('../../lib/typescript-overrides', {
typescript,
})

typescriptOverrides.overrideSourceMaps(true)

expect(typescriptOverrides.getSourceMapOverride()).to.be.true

typescript.createProgram({
options: {
sourceMap: false,
inlineSources: true,
inlineSourceMap: true,
},
})

expect(createProgram).to.be.calledOn(typescript)
expect(createProgram).to.be.calledWith({
options: {
sourceMap: true,
},
})
})

it('it sets sourceMap: false', () => {
const typescriptOverrides = proxyquire('../../lib/typescript-overrides', {
typescript,
})

typescriptOverrides.overrideSourceMaps(false)

expect(typescriptOverrides.getSourceMapOverride()).to.be.false

typescript.createProgram({
options: {
sourceMap: true,
inlineSources: true,
inlineSourceMap: true,
},
})

expect(createProgram).to.be.calledOn(typescript)
expect(createProgram).to.be.calledWith({
options: {
sourceMap: false,
},
})
})

it('does not override sourcemaps', () => {
const typescriptOverrides = proxyquire('../../lib/typescript-overrides', {
typescript,
})

expect(typescriptOverrides.getSourceMapOverride()).to.be.null

typescript.createProgram({
options: {
sourceMap: true,
inlineSources: true,
inlineSourceMap: true,
},
})

expect(createProgram).to.be.calledOn(typescript)
expect(createProgram).to.be.calledWith({
options: {
sourceMap: true,
inlineSources: true,
inlineSourceMap: true,
},
})
})
})
})
Loading

0 comments on commit 1afdc0a

Please sign in to comment.