Skip to content

Commit 01b11fe

Browse files
committed
Use ESM
1 parent b2dd046 commit 01b11fe

File tree

9 files changed

+102
-66
lines changed

9 files changed

+102
-66
lines changed

index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
'use strict'
2-
31
/**
42
* @typedef {import('./lib/react-markdown.js').ReactMarkdownOptions} Options
53
* @typedef {import('./lib/ast-to-react.js').Components} Components
64
*/
75

8-
module.exports = require('./lib/react-markdown.js')
6+
import {ReactMarkdown} from './lib/react-markdown.js'
7+
8+
export default ReactMarkdown

lib/ast-to-react.js

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
1-
'use strict'
2-
3-
const React = require('react')
4-
const ReactIs = require('react-is')
5-
const svg = require('property-information/svg')
6-
const find = require('property-information/find')
7-
const hastToReact = require('property-information/hast-to-react.json')
8-
const spaces = require('space-separated-tokens')
9-
const commas = require('comma-separated-tokens')
10-
const style = require('style-to-object')
11-
12-
exports.hastToReact = toReact
13-
exports.hastChildrenToReact = childrenToReact
1+
import React from 'react'
2+
import ReactIs from 'react-is'
3+
import {svg, find, hastToReact} from 'property-information'
4+
import spaces from 'space-separated-tokens'
5+
import commas from 'comma-separated-tokens'
6+
import style from 'style-to-object'
147

158
/**
169
* @typedef {JSX.IntrinsicElements} IntrinsicElements
@@ -38,10 +31,7 @@ exports.hastChildrenToReact = childrenToReact
3831
* @property {boolean} mustUseProperty
3932
* @property {boolean} defined
4033
*
41-
* @typedef Schema
42-
* @property {Object.<string, Info>} property
43-
* @property {Object.<string, string>} normal
44-
* @property {string?} space
34+
* @typedef {import('property-information').Schema} Schema
4535
*
4636
* @typedef Raw
4737
* @property {'raw'} type
@@ -151,7 +141,7 @@ const tableElements = new Set(['table', 'thead', 'tbody', 'tfoot', 'tr'])
151141
* @param {Context} context
152142
* @param {Element|Root} node
153143
*/
154-
function childrenToReact(context, node) {
144+
export function childrenToReact(context, node) {
155145
/** @type {Array.<ReactNode>} */
156146
const children = []
157147
let childIndex = -1
@@ -400,7 +390,6 @@ function getElementsBeforeCount(parent, node) {
400390
* @param {Context} ctx
401391
*/
402392
function addProperty(props, prop, value, ctx) {
403-
/** @type {Info} */
404393
const info = find(ctx.schema, prop)
405394
let result = value
406395

lib/react-markdown.js

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
'use strict'
2-
3-
const React = require('react')
4-
const vfile = require('vfile')
5-
const unified = require('unified')
6-
const parse = require('remark-parse')
7-
const remarkRehype = require('remark-rehype')
8-
const PropTypes = require('prop-types')
9-
const html = require('property-information/html')
10-
const filter = require('./rehype-filter.js')
11-
const uriTransformer = require('./uri-transformer.js')
12-
const childrenToReact = require('./ast-to-react.js').hastChildrenToReact
1+
import React from 'react'
2+
import vfile from 'vfile'
3+
import unified from 'unified'
4+
import parse from 'remark-parse'
5+
import remarkRehype from 'remark-rehype'
6+
import PropTypes from 'prop-types'
7+
import {html} from 'property-information'
8+
import rehypeFilter from './rehype-filter.js'
9+
import {uriTransformer} from './uri-transformer.js'
10+
import {childrenToReact} from './ast-to-react.js'
1311

1412
/**
1513
* @typedef {import('react').ReactNode} ReactNode
@@ -33,8 +31,6 @@ const childrenToReact = require('./ast-to-react.js').hastChildrenToReact
3331
* @typedef {CoreOptions & PluginOptions & LayoutOptions & FilterOptions & TransformOptions} ReactMarkdownOptions
3432
*/
3533

36-
module.exports = ReactMarkdown
37-
3834
const own = {}.hasOwnProperty
3935
const changelog =
4036
'https://github.com/remarkjs/react-markdown/blob/main/changelog.md'
@@ -76,7 +72,7 @@ const deprecated = {
7672
* @param {ReactMarkdownOptions} options
7773
* @returns {ReactElement}
7874
*/
79-
function ReactMarkdown(options) {
75+
export function ReactMarkdown(options) {
8076
for (const key in deprecated) {
8177
if (own.call(deprecated, key) && own.call(options, key)) {
8278
/** @type {Deprecation} */
@@ -96,7 +92,7 @@ function ReactMarkdown(options) {
9692
.use(options.remarkPlugins || options.plugins || [])
9793
.use(remarkRehype, {allowDangerousHtml: true})
9894
.use(options.rehypePlugins || [])
99-
.use(filter, options)
95+
.use(rehypeFilter, options)
10096

10197
/** @type {vfile} */
10298
let file

lib/rehype-filter.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
const visit = require('unist-util-visit')
2-
3-
module.exports = rehypeFilter
1+
import visit from 'unist-util-visit'
42

53
/**
64
* @typedef {import('unist').Node} Node
@@ -23,7 +21,7 @@ module.exports = rehypeFilter
2321
/**
2422
* @type {import('unified').Plugin<[RehypeFilterOptions]>}
2523
*/
26-
function rehypeFilter(options) {
24+
export default function rehypeFilter(options) {
2725
if (options.allowedElements && options.disallowedElements) {
2826
throw new TypeError(
2927
'Only one of `allowedElements` and `disallowedElements` should be defined'

lib/uri-transformer.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
const protocols = ['http', 'https', 'mailto', 'tel']
22

3-
module.exports = uriTransformer
4-
53
/**
64
* @param {string} uri
75
* @returns {string}
86
*/
9-
function uriTransformer(uri) {
7+
export function uriTransformer(uri) {
108
const url = (uri || '').trim()
119
const first = url.charAt(0)
1210

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@
6767
"Dennis S <denis.s@svsg.co>",
6868
"Evan Hensleigh <futuraprime@gmail.com>"
6969
],
70-
"types": "index.d.ts",
70+
"sideEffects": false,
71+
"type": "module",
7172
"main": "index.js",
73+
"types": "index.d.ts",
7274
"unpkg": "react-markdown.min.js",
7375
"files": [
7476
"lib/",
@@ -81,7 +83,7 @@
8183
"@types/unist": "^2.0.3",
8284
"comma-separated-tokens": "^1.0.0",
8385
"prop-types": "^15.7.2",
84-
"property-information": "^5.3.0",
86+
"property-information": "^6.0.0",
8587
"react-is": "^17.0.0",
8688
"remark-parse": "^9.0.0",
8789
"remark-rehype": "^8.0.0",
@@ -101,7 +103,6 @@
101103
"@types/react-is": "^17.0.0",
102104
"c8": "^7.8.0",
103105
"esbuild": "^0.12.0",
104-
"esbuild-register": "^2.6.0",
105106
"eslint-config-xo-react": "^0.25.0",
106107
"eslint-plugin-es": "^4.0.0",
107108
"eslint-plugin-react": "^7.0.0",
@@ -130,7 +131,7 @@
130131
"build": "run-s build:*",
131132
"format": "remark . -qfo --ignore-pattern test/ && prettier . -w --loglevel warn && xo --fix",
132133
"test": "run-s build format test:coverage",
133-
"test:unit": "uvu -r esbuild-register test",
134+
"test:unit": "node --no-warnings --experimental-loader=./test/loader.js ./node_modules/.bin/uvu test \"\\.jsx$\"",
134135
"test:coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov npm run test:unit"
135136
},
136137
"browserslist": "> 0.25%, not dead",
@@ -201,6 +202,7 @@
201202
"test/**/*.jsx"
202203
],
203204
"rules": {
205+
"node/file-extension-in-import": 0,
204206
"react/no-children-prop": 0,
205207
"react/prop-types": 0
206208
}

test/loader.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import path from 'path'
2+
import {fileURLToPath} from 'url'
3+
import {transformSync} from 'esbuild'
4+
5+
const {getFormat, transformSource} = createLoader()
6+
7+
export {getFormat, transformSource}
8+
9+
/**
10+
* A tiny JSX loader.
11+
*/
12+
export function createLoader() {
13+
return {getFormat, transformSource}
14+
15+
/**
16+
* @param {string} url
17+
* @param {unknown} context
18+
* @param {Function} defaultGetFormat
19+
*/
20+
function getFormat(url, context, defaultGetFormat) {
21+
return path.extname(url) === '.jsx'
22+
? {format: 'module'}
23+
: defaultGetFormat(url, context, defaultGetFormat)
24+
}
25+
26+
/**
27+
* @param {Buffer} value
28+
* @param {{url: string, [x: string]: unknown}} context
29+
* @param {Function} defaultTransformSource
30+
*/
31+
async function transformSource(value, context, defaultTransformSource) {
32+
if (path.extname(context.url) !== '.jsx') {
33+
return defaultTransformSource(value, context, defaultTransformSource)
34+
}
35+
36+
const {code, warnings} = transformSync(String(value), {
37+
sourcefile: fileURLToPath(context.url),
38+
sourcemap: 'both',
39+
loader: 'jsx',
40+
target: 'esnext',
41+
format: context.format === 'module' ? 'esm' : 'cjs'
42+
})
43+
44+
if (warnings && warnings.length > 0) {
45+
for (const warning of warnings) {
46+
console.log(warning.location)
47+
console.log(warning.text)
48+
}
49+
}
50+
51+
return {source: code}
52+
}
53+
}

test/test.jsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
const {test} = require('uvu')
2-
const assert = require('uvu/assert')
3-
const fs = require('fs')
4-
const path = require('path')
5-
const React = require('react')
6-
const gfm = require('remark-gfm')
7-
const visit = require('unist-util-visit')
8-
const ReactDom = require('react-dom/server')
9-
const raw = require('rehype-raw')
10-
const Markdown = require('../index.js')
11-
const toc = require('remark-toc')
1+
import {test} from 'uvu'
2+
import * as assert from 'uvu/assert'
3+
import fs from 'fs'
4+
import path from 'path'
5+
import React from 'react'
6+
import gfm from 'remark-gfm'
7+
import visit from 'unist-util-visit'
8+
import raw from 'rehype-raw'
9+
import toc from 'remark-toc'
10+
import ReactDom from 'react-dom/server.js'
11+
import Markdown from '../index.js'
1212

1313
const own = {}.hasOwnProperty
1414

@@ -978,10 +978,10 @@ test('should throw on invalid component', () => {
978978

979979
test('can render the whole spectrum of markdown within a single run', () => {
980980
const input = String(
981-
fs.readFileSync(path.join(__dirname, 'fixtures', 'runthrough.md'))
981+
fs.readFileSync(path.join('test', 'fixtures', 'runthrough.md'))
982982
)
983983
const expected = String(
984-
fs.readFileSync(path.join(__dirname, 'fixtures', 'runthrough.html'))
984+
fs.readFileSync(path.join('test', 'fixtures', 'runthrough.html'))
985985
)
986986

987987
const actual = asHtml(

tsconfig.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
{
2-
"include": ["lib/**.js", "test/**.jsx", "index.js"],
2+
"include": ["lib/**/*.js", "test/**/*.jsx", "test/**/*.js", "index.js"],
33
"exclude": ["**/*.min.js"],
44
"compilerOptions": {
5-
"target": "ES2015",
6-
"lib": ["ES2015", "DOM"],
5+
"target": "ES2020",
6+
"lib": ["ES2020", "DOM"],
7+
"module": "ES2020",
78
"moduleResolution": "node",
89
"jsx": "react",
910
"allowJs": true,
1011
"checkJs": true,
1112
"declaration": true,
1213
"emitDeclarationOnly": true,
1314
"allowSyntheticDefaultImports": true,
14-
"resolveJsonModule": true,
1515
"skipLibCheck": true,
1616
"noImplicitAny": false,
1717
"noImplicitThis": true,

0 commit comments

Comments
 (0)