Skip to content
This repository has been archived by the owner on Jan 31, 2023. It is now read-only.

feat: Add out-of-the-tbox typescript support #38

Merged
merged 18 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,16 @@ browserify({
})
```

### typescript

When the path to the TypeScript package is given, Cypress will automatically transpile `.ts` spec, plugin, support files. Note that this **DOES NOT** check types.

```javascript
browserify({
typescript: require.resolve('typescript')
})
```

**Default**: `undefined`

## Modifying default options
Expand Down
16 changes: 14 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const defaultOptions = {
},
}

const getBrowserifyOptions = (entry, userBrowserifyOptions = {}) => {
const getBrowserifyOptions = (entry, userBrowserifyOptions = {}, typescriptPath = null) => {
let browserifyOptions = cloneDeep(defaultOptions.browserifyOptions)

// allow user to override default options
Expand All @@ -81,6 +81,18 @@ const getBrowserifyOptions = (entry, userBrowserifyOptions = {}) => {
entries: [entry],
})

if (typescriptPath) {
browserifyOptions.extensions.push('.ts', '.tsx')
// remove babelify setting
browserifyOptions.transform.pop()
sainthkh marked this conversation as resolved.
Show resolved Hide resolved
// add typescript compiler
browserifyOptions.transform.push([
path.join(__dirname, './simple_tsify'), {
typescript: require(typescriptPath),
},
])
}

debug('browserifyOptions: %o', browserifyOptions)

return browserifyOptions
Expand Down Expand Up @@ -127,7 +139,7 @@ const preprocessor = (options = {}) => {
debug('input:', filePath)
debug('output:', outputPath)

const browserifyOptions = getBrowserifyOptions(filePath, options.browserifyOptions)
const browserifyOptions = getBrowserifyOptions(filePath, options.browserifyOptions, options.typescript)
const watchifyOptions = Object.assign({}, defaultOptions.watchifyOptions, options.watchifyOptions)

const bundler = browserify(browserifyOptions)
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
"semantic-release": "15.13.15",
"sinon": "7.2.3",
"sinon-chai": "3.3.0",
"snap-shot-it": "7.9.2"
"snap-shot-it": "7.9.2",
"typescript": "3.8.3"
},
"dependencies": {
"@babel/core": "7.4.5",
Expand All @@ -74,7 +75,8 @@
"debug": "4.1.1",
"fs-extra": "7.0.1",
"lodash.clonedeep": "4.5.0",
"watchify": "3.11.1"
"watchify": "3.11.1",
"through2": "^2.0.0"
},
"release": {
"analyzeCommits": {
Expand Down
39 changes: 39 additions & 0 deletions simple_tsify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
let through = require('through2')

const isJson = (code) => {
try {
JSON.parse(code)
} catch (e) {
return false
}

return true
}

module.exports = function (b, opts) {
sainthkh marked this conversation as resolved.
Show resolved Hide resolved
const chunks = []

return through(
(buf, enc, next) => {
chunks.push(buf.toString())
next()
},
function (next) {
const ts = opts.typescript
const text = chunks.join('')

if (isJson(text)) {
this.push(text)
} else {
this.push(ts.transpileModule(text, {
compilerOptions: {
esModuleInterop: true,
jsx: 'react',
},
}).outputText)
}

next()
},
)
}
28 changes: 28 additions & 0 deletions test/e2e/e2e_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,34 @@ describe('browserify preprocessor - e2e', function () {
})
})

describe('typescript', function () {
it('handles .ts file when the path is given', function () {
return bundle('math_spec.ts', {
typescript: require.resolve('typescript'),
}).then((output) => {
// check that bundled tests work
eval(output)
})
})

it('handles .tsx file when the path is given', function () {
return bundle('math_spec.ts', {
typescript: require.resolve('typescript'),
}).then((output) => {
// check that bundled tests work
eval(output)
})
})

it('cannot handle .ts file when the path is not given', function () {
expect(() => bundle('math_spec.ts')).to.throw
})

it('cannot handle .tsx file when the path is not given', function () {
expect(() => bundle('math_spec.tsx')).to.throw
})
})

describe('imports and exports', () => {
it('handles imports and exports', () => {
return bundle('math_spec.js').then((output) => {
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/math.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
add: (a: number, b: number) => {
return a + b
},
}
13 changes: 13 additions & 0 deletions test/fixtures/math_spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// math exports default object
// so if we want a property, first we need to grab the default
import math from './math'
const {add} = math

context('math.js', function () {
it('imports function', () => {
expect(add, 'add').to.be.a('function')
})
it('can add numbers', function () {
expect(add(1, 2)).to.eq(3)
})
})
9 changes: 9 additions & 0 deletions test/fixtures/math_spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import math from './math'
sainthkh marked this conversation as resolved.
Show resolved Hide resolved

interface Props {
greeting: string
}

export const Foo = ({ greeting }: Props) => {
return <div>{greeting}{math.add(1, 2)}</div>
}