Skip to content

Latest commit

 

History

History
124 lines (97 loc) · 4.13 KB

GLOBALIZING-GUIDE-MJS.md

File metadata and controls

124 lines (97 loc) · 4.13 KB

Home | Full API | Tutorial | Project Setup Guide (CJS / MJS)

Guide To Globalizing The FP Language Elements: ES Modules

You've chosen ES Modules. We are the hipsters who use the latest tech, but we tend to have compatibility problems with some popular dev tools which can make us a little harder to work with.

Global Import File

We recommend having a global file whose job it is to set up all global language elements. This file can then be imported in an index.js file or in a test setup or any other entry point to the system. This also provides a convenient place to introduce/modify language elements, something most FP Light users choose to do as they start using the library.

// ./fp.js
import * as fp from '@sullux/fp-light'

export const customGlobals = {
  ...fp,
  // add other globals here, such as:
  // globalThis.key: _[0]
  // globalThis.value: _[1]
}
// globalize it
Object.assign(globalThis, customGlobals)
// export it (you may need this later for your linter!)

Now in your entry points (such as index.js) you can just import this one file, such as:

// index.js
import '../fp.js'

// rest of your index.js code here

Jest

Jest has a few ways to set up the global scope. After experimenting, the best way seems to be to use the globalSetup option in the Jest config. WARNING: as far as we can tell, Jest only supports CJS. That means the setup file (below) must use require and module.exports.

// in jest.config.js
module.exports = {
  // ...other setup
  globalSetup: './jestSetup.js',
}

Which requires you to create the jest setup file itself:

// ./jestSetup.js
module.exports = () => {
  require('./fp') // set up the global scope
}

Jest requires this module to export a function, so we obey.

Linter

This is a big topic with lots of possibilities that we won't go into here. Luckily, most linters seem to have one important concept, and that is a list of known globals. For FP Light it's a pretty long list. We use standardx ourselves. That allows us to dump our globals straight into our package.json file as:

{
  "standardx": {
    "global": [
      "_",
      "baseIdentity",
      "baseArgument",
      "_base",
      "thisIdentity",
      "thisArgument",
      "_this",
      "isResolve",
      "resolve",
      // etc.
    ]
  }
}

Since standardx is based on eslint, another (better?) option is to put these in the .eslintrc file. Either way, you can do this as a one-time step or you can use a script to do it for you. We like the idea of building the globals list as a build step, but either way, it's useful to add a script to your package.json. Ours looks like this:

{
  "scripts": {
    // you can run this with `yarn globals`` or `npm run globals`
    "globals": "node ./setupGlobals.js"
  }
}
// ./setupGlobals.js
import { readFileSync, writeFileSync } from 'fs'
import { customGlobals } from './fp'

const readEslint = () => {
  try {
    return JSON.parse(readFileSync('./.eslintrc').toString())
  } catch() {
    return {}
  }
}
const eslint = readEslint()
const existingGlobals = eslint.globals || []

const customGlobalNames = Object.keys(customGlobals)
const globals = [...(new Set([...existingGlobals, ...customGlobalNames]))]

const newEslint = {
  ...eslint,
  globals,
}

writeFileSync('./.eslintrc', JSON.stringify(newEslint, null, 2))

Now, either explicitly or as part of your build, whenever you modify your global setup file you can run yarn globals or npm run globals and your changes will be reflected in your .eslintrc file. Note that the above logic is additive, so if you want to remove a global you will need to edit the .eslintrc file by hand to remove it.