Skip to content

Commit

Permalink
fix(umd): do umd manually
Browse files Browse the repository at this point in the history
Rollup is not capable of exposing a default export AND a named export as
a UMD module in a useful way for the global context. So this adds some
custom UMD logic to the bottom of the main file. This should hopefully
never need to be touched, but there are tests that validate the CJS and
ES6 module exports.

Things will be challenging when people want to use native ES6 modules
with this module (because now we're not exposing this as a native ES6
module). But we weren't really doing that in the first place (we were
transpiling) so that's fine for now.

Fixes #14
  • Loading branch information
Kent C. Dodds committed Aug 31, 2016
1 parent 774ca9c commit 8c221e3
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 9 deletions.
65 changes: 65 additions & 0 deletions dist-test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint import/default:0, import/named:0, import/no-unresolved:0, import/extensions:0, no-console:0 */
/*
* This file is here to validate that the built version of the library exposes the module in the way that we
* want it to. Specifically that the ES6 module import can get the matchSorter function via default import and the
* rankings via named import. Also that the CommonJS require returns the matchSorter function (rather than an object
* that has the matchSorter as a `default` property).
*
* This file is unable to validate the AMD or global exports.
*/
import assert from 'assert'

import cjsImport, {rankings as cjsRankings} from '../dist/cjs'
import umdImport, {rankings as umdRankings} from '../dist/umd/match-sorter'

const cjsRequire = require('../dist/cjs')
const umdRequire = require('../dist/umd/match-sorter')


assert(
isMatchSorterFunction(cjsImport) && isRankingsObject(cjsRankings),
'CJS build has a problem with ES6 modules'
)

assert(
isMatchSorterFunction(cjsRequire),
'CJS build has a problem with CJS'
)

assert(
isMatchSorterFunction(umdImport) && isRankingsObject(umdRankings),
'UMD build has a problem with ES6 modules'
)

assert(
isMatchSorterFunction(umdRequire),
'UMD build has a problem with CJS'
)

// TODO: how could we validate the AMD/global modules?

console.log('Built modules look good 👍')

function isMatchSorterFunction(thing) {
if (typeof thing !== 'function') {
console.error(`matchSorter thing should be a function. It's a ${typeof thing}`)
return false
}
if (thing.name !== 'matchSorter') {
console.error(`the function is not called "matchSorter". It's called ${thing.name}`)
return false
}
return isRankingsObject(thing.rankings)
}

function isRankingsObject(thing) {
if (typeof thing !== 'object') {
console.error(`rankings object thing should be an object. It's a ${typeof thing}`)
return false
}
if (!Object.keys(thing).includes('NO_MATCH')) {
console.error(`rankings object should include a NO_MATCH key. It only has ${Object.keys(thing)}`)
return false
}
return true
}
32 changes: 31 additions & 1 deletion package-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ module.exports = {
description: 'Run AVA in watch mode',
script: 'ava -w --require babel-register',
},
build: {
description: 'validates the built files',
script: 'babel-node dist-test/index.js',
watch: {
description: 'watches the dist directory for changes and reruns test.build when it changes',
script: watch(['dist-test/**/*.js', 'dist/**/*.js'], 'npm start -s test.build'),
},
},
},
build: {
description: 'delete the dist directory and run all builds',
Expand All @@ -29,6 +37,20 @@ module.exports = {
script: 'cross-env MINIFY=true rollup --config --sourcemap',
},
},
watch: {
description: 'watches the filesystem for changes and reruns the build when changes have been made',
script: watchSrc('npm start -s build'),
},
},
dev: {
build: {
description: 'helps while working on the module build and tests',
script: 'p-s -p build.watch,test.build.watch',
},
coverage: {
description: 'runs tests as files change in `src`',
script: watchSrc('p-s test'),
},
},
lint: {
description: 'lint the entire project',
Expand All @@ -44,7 +66,7 @@ module.exports = {
},
validate: {
description: 'This runs several scripts to make sure things look good before committing or on clean install',
script: 'p-s -p lint,build,test',
script: 'p-s -p lint,build,test && p-s test.build',
},
addContributor: {
description: 'When new people contribute to the project, run this',
Expand All @@ -59,3 +81,11 @@ module.exports = {
silent: false,
},
}

function watch(paths, command) {
return `nodemon --quiet ${paths.map(p => `--watch ${p}`).join(' ')} --exec "${command}"`
}

function watchSrc(command) {
return watch(['src/**/*.js'], command)
}
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
"author": "Kent C. Dodds <[email protected]> (http://kentcdodds.com/)",
"license": "MIT",
"bundledDependencies": [
"diacritic"
"diacritic",
"global-object"
],
"dependencies": {
"diacritic": "0.0.2"
"diacritic": "0.0.2",
"global-object": "1.0.0"
},
"devDependencies": {
"all-contributors-cli": "^3.0.0",
Expand All @@ -34,6 +36,7 @@
"eslint": "^3.1.1",
"eslint-config-kentcdodds": "^10.0.1",
"ghooks": "^1.3.2",
"nodemon": "1.10.2",
"nyc": "8.1.0",
"opt-cli": "^1.4.2",
"p-s": "^2.3.0",
Expand Down
4 changes: 1 addition & 3 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ const filename = process.env.MINIFY ? 'match-sorter.min.js' : 'match-sorter.js'
export default {
entry: 'src/index.js',
dest: `dist/umd/${filename}`,
format: 'umd',
moduleName: 'matchSorter',
exports: 'none',
plugins: [
nodeResolve({jsnext: true, main: true}),
commonjs({include: 'node_modules/**'}),
rollupBabel({exclude: 'node_modules/**'}),
process.env.MINIFY ? uglify() : null,
].filter(i => !!i),
exports: 'named',
}
15 changes: 13 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @author Kent C. Dodds <[email protected]>
*/
import diacritics from 'diacritic'
import globalObject from 'global-object'

const rankings = {
EQUAL: 6,
Expand All @@ -17,7 +18,6 @@ const rankings = {
}

matchSorter.rankings = rankings
export {matchSorter as default, rankings}

/**
* Takes an array of items and a value and returns a new array with the items that match the given value
Expand Down Expand Up @@ -227,4 +227,15 @@ function getAllValuesToRank(item, keys) {
return keys.reduce((allVals, key) => allVals.concat(getItemValue(item, key)), [])
}

module.exports = exports.default // CommonJS compat
// some manual ✨ magic umd ✨ here because Rollup isn't capable of exposing our module the way we want
// see dist-test/index.js
/* istanbul ignore next */
if (typeof exports === 'object' && typeof module !== 'undefined') {
matchSorter.default = matchSorter
Object.defineProperty(exports, '__esModule', {value: true})
module.exports = matchSorter
} else if (typeof define === 'function' && define.amd) { // eslint-disable-line
define(() => matchSorter) // eslint-disable-line
} else {
globalObject.matchSorter = matchSorter // eslint-disable-line
}
3 changes: 2 additions & 1 deletion src/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint ava/no-only-test:0, ava/no-skip-test:0 */
import test from 'ava'
import matchSorter, {rankings} from './'
// have to disable eslint for the next line because we have to do weird things to make things work with UMD
import matchSorter, {rankings} from './' // eslint-disable-line import/default,import/named

const tests = {
'returns an empty array with a string that is too long': {
Expand Down

0 comments on commit 8c221e3

Please sign in to comment.