diff --git a/packages/loader/readme.md b/packages/loader/readme.md
index 4eaec6f4e..8b1542450 100644
--- a/packages/loader/readme.md
+++ b/packages/loader/readme.md
@@ -31,14 +31,14 @@ module: {
// …
{
test: /\.mdx$/,
- use: ['babel-loader', '@mdx-js/loader']
+ use: ['@mdx-js/loader']
}
]
}
```
-You’ll probably want to configure Babel to use `@babel/preset-react` or so, but
-that’s not required.
+You might want to add `babel-loader` there too if you have modern JS features
+that you want to compile down.
All options given to `mdx-js/loader`, except for `renderer` (see below), are
passed to MDX itself:
diff --git a/packages/loader/test/index.test.js b/packages/loader/test/index.test.js
index e073eb0a7..fa70f0393 100644
--- a/packages/loader/test/index.test.js
+++ b/packages/loader/test/index.test.js
@@ -20,20 +20,7 @@ const transform = (filePath, options) => {
rules: [
{
test: /\.mdx$/,
- use: [
- {
- loader: 'babel-loader',
- options: {
- configFile: false,
- plugins: [
- '@babel/plugin-transform-runtime',
- '@babel/plugin-syntax-jsx',
- '@babel/plugin-transform-react-jsx'
- ]
- }
- },
- {loader: path.resolve(__dirname, '..'), options}
- ]
+ use: [{loader: path.resolve(__dirname, '..'), options}]
}
]
}
@@ -64,13 +51,8 @@ const run = value => {
// return new Function(val)().default
// Replace import/exports w/ parameters and return value.
const val = value
- .replace(
- /import _objectWithoutProperties from "@babel\/runtime\/helpers\/objectWithoutProperties";/,
- ''
- )
- .replace(/import _extends from "@babel\/runtime\/helpers\/extends";/, '')
- .replace(/import React from 'react';/, '')
- .replace(/import \{ mdx } from '@mdx-js\/react';/, '')
+ .replace(/import React from 'react'/, '')
+ .replace(/import \{mdx} from '@mdx-js\/react'/, '')
.replace(/export default/, 'return')
// eslint-disable-next-line no-new-func
diff --git a/packages/mdx/estree-to-js.js b/packages/mdx/estree-to-js.js
index f05a5c9c9..9b86628b5 100644
--- a/packages/mdx/estree-to-js.js
+++ b/packages/mdx/estree-to-js.js
@@ -20,7 +20,7 @@ const customGenerator = Object.assign({}, astring.baseGenerator, {
})
function estreeToJs(estree) {
- return astring.generate(estree, {generator: customGenerator})
+ return astring.generate(estree, {generator: customGenerator, comments: true})
}
// `attr="something"`
diff --git a/packages/mdx/index.js b/packages/mdx/index.js
index b5ea9a823..433e10a91 100644
--- a/packages/mdx/index.js
+++ b/packages/mdx/index.js
@@ -6,10 +6,6 @@ const minifyWhitespace = require('rehype-minify-whitespace')
const mdxAstToMdxHast = require('./mdx-ast-to-mdx-hast')
const mdxHastToJsx = require('./mdx-hast-to-jsx')
-const pragma = `/* @jsxRuntime classic */
-/* @jsx mdx */
-/* @jsxFrag mdx.Fragment */`
-
function createMdxAstCompiler(options = {}) {
return unified()
.use(remarkParse)
@@ -37,13 +33,13 @@ function createConfig(mdx, options) {
}
function sync(mdx, options = {}) {
- const file = createCompiler(options).processSync(createConfig(mdx, options))
- return pragma + '\n' + String(file)
+ return String(createCompiler(options).processSync(createConfig(mdx, options)))
}
async function compile(mdx, options = {}) {
- const file = await createCompiler(options).process(createConfig(mdx, options))
- return pragma + '\n' + String(file)
+ return String(
+ await createCompiler(options).process(createConfig(mdx, options))
+ )
}
module.exports = compile
diff --git a/packages/mdx/mdx-hast-to-jsx.js b/packages/mdx/mdx-hast-to-jsx.js
index e739e258d..6a56169e2 100644
--- a/packages/mdx/mdx-hast-to-jsx.js
+++ b/packages/mdx/mdx-hast-to-jsx.js
@@ -1,5 +1,6 @@
const toEstree = require('hast-util-to-estree')
const walk = require('estree-walker').walk
+const buildJsx = require('estree-util-build-jsx')
const periscopic = require('periscopic')
const estreeToJs = require('./estree-to-js')
@@ -7,6 +8,7 @@ function serializeEstree(estree, options) {
const {
// Default options
skipExport = false,
+ keepJsx = false,
wrapExport
} = options
@@ -150,6 +152,13 @@ function serializeEstree(estree, options) {
exports.push({type: 'ExportDefaultDeclaration', declaration: declaration})
}
+ // Add JSX pragma comments.
+ estree.comments.unshift(
+ {type: 'Block', value: '@jsxRuntime classic'},
+ {type: 'Block', value: '@jsx mdx'},
+ {type: 'Block', value: '@jsxFrag mdx.Fragment'}
+ )
+
estree.body = [
...createMakeShortcodeHelper(
magicShortcodes,
@@ -159,6 +168,10 @@ function serializeEstree(estree, options) {
...exports
]
+ if (!keepJsx) {
+ buildJsx(estree)
+ }
+
return estreeToJs(estree)
}
diff --git a/packages/mdx/package.json b/packages/mdx/package.json
index c25bb84fc..e1c0d1984 100644
--- a/packages/mdx/package.json
+++ b/packages/mdx/package.json
@@ -47,6 +47,7 @@
"astring": "^1.4.0",
"detab": "^2.0.0",
"estree-walker": "^2.0.0",
+ "estree-util-build-jsx": "^1.0.0",
"hast-util-to-estree": "^1.1.0",
"mdast-util-to-hast": "^10.1.0",
"periscopic": "^2.0.0",
diff --git a/packages/mdx/test/index.test.js b/packages/mdx/test/index.test.js
index 6ad30e603..84c361a82 100644
--- a/packages/mdx/test/index.test.js
+++ b/packages/mdx/test/index.test.js
@@ -19,7 +19,6 @@ const run = async (value, options = {}) => {
const {code} = await babel.transformAsync(doc, {
configFile: false,
plugins: [
- '@babel/plugin-transform-react-jsx',
path.resolve(__dirname, '../../babel-plugin-remove-export-keywords')
]
})
@@ -30,13 +29,19 @@ const run = async (value, options = {}) => {
}
describe('@mdx-js/mdx', () => {
- it('should generate JSX', async () => {
+ it('should generate JS (by default)', async () => {
const result = await mdx('Hello World')
+ expect(result).toMatch(/mdx\("p", null, "Hello World"\)/)
+ })
+
+ it('should generate JSX (`keepJsx: true`)', async () => {
+ const result = await mdx('Hello World', {keepJsx: true})
+
expect(result).toMatch(/
\{"Hello World"\}<\/p>/)
})
- it('should generate runnable JSX', async () => {
+ it('should generate runnable JS', async () => {
const Content = await run('Hello World')
expect(renderToStaticMarkup()).toEqual(
@@ -396,7 +401,7 @@ describe('@mdx-js/mdx', () => {
rehypePlugins: [plugin]
})
- expect(result).toMatch(/export const A = \(\) => !<\/b>/)
+ expect(result).toMatch(/export const A = \(\) => mdx\("b", null, "!"\)/)
})
it('should crash on incorrect exports', async () => {
@@ -711,24 +716,24 @@ describe('@mdx-js/mdx', () => {
describe('default', () => {
it('should be async', async () => {
- expect(mdx('x')).resolves.toMatch(/
{"x"}<\/p>/)
+ expect(mdx('x')).resolves.toMatch(/mdx\("p", null, "x"\)/)
})
it('should support `remarkPlugins`', async () => {
expect(mdx('$x$', {remarkPlugins: [math]})).resolves.toMatch(
- /className="math math-inline"/
+ /className: "math math-inline"/
)
})
})
describe('sync', () => {
it('should be sync', () => {
- expect(mdx.sync('x')).toMatch(/
{"x"}<\/p>/)
+ expect(mdx.sync('x')).toMatch(/mdx\("p", null, "x"\)/)
})
it('should support `remarkPlugins`', () => {
expect(mdx.sync('$x$', {remarkPlugins: [math]})).toMatch(
- /className="math math-inline"/
+ /className: "math math-inline"/
)
})
})
@@ -772,7 +777,7 @@ describe('createMdxAstCompiler', () => {
describe('createCompiler', () => {
it('should create a unified processor', () => {
expect(String(mdx.createCompiler().processSync('x'))).toMatch(
- /
{"x"}<\/p>/
+ /mdx\("p", null, "x"\)/
)
})
})
@@ -817,6 +822,6 @@ describe('mdx-hast-to-jsx', () => {
const doc = unified().use(toJsx).stringify(tree)
expect(doc).toMatch(/export default MDXContent/)
- expect(doc).toMatch(/\{"a"}<\/x>/)
+ expect(doc).toMatch(/mdx\("x", null, "a"\)/)
})
})
diff --git a/packages/preact/test/test.js b/packages/preact/test/test.js
index dd715e064..f80d9f0e8 100644
--- a/packages/preact/test/test.js
+++ b/packages/preact/test/test.js
@@ -15,7 +15,6 @@ const run = async value => {
const {code} = await babelTransform(doc, {
configFile: false,
plugins: [
- '@babel/plugin-transform-react-jsx',
path.resolve(__dirname, '../../babel-plugin-remove-export-keywords')
]
})
diff --git a/packages/react/test/test.js b/packages/react/test/test.js
index 3bf34409d..6901bf585 100644
--- a/packages/react/test/test.js
+++ b/packages/react/test/test.js
@@ -15,7 +15,6 @@ const run = async value => {
const {code} = await babelTransform(doc, {
configFile: false,
plugins: [
- '@babel/plugin-transform-react-jsx',
path.resolve(__dirname, '../../babel-plugin-remove-export-keywords')
]
})
diff --git a/packages/runtime/package.json b/packages/runtime/package.json
index cd8a6defd..43a8fc9a5 100644
--- a/packages/runtime/package.json
+++ b/packages/runtime/package.json
@@ -53,8 +53,7 @@
},
"dependencies": {
"@mdx-js/mdx": "^2.0.0-next.8",
- "@mdx-js/react": "^2.0.0-next.8",
- "buble-jsx-only": "^0.19.8"
+ "@mdx-js/react": "^2.0.0-next.8"
},
"devDependencies": {
"microbundle": "^0.12.0",
diff --git a/packages/runtime/src/index.js b/packages/runtime/src/index.js
index 5a0967174..aab92f4c6 100644
--- a/packages/runtime/src/index.js
+++ b/packages/runtime/src/index.js
@@ -1,5 +1,4 @@
import React from 'react'
-import {transform} from 'buble-jsx-only'
import mdx from '@mdx-js/mdx'
import {MDXProvider, mdx as createElement} from '@mdx-js/react'
@@ -25,7 +24,7 @@ export default ({
...scope
}
- const jsx = mdx
+ const js = mdx
.sync(children, {
remarkPlugins,
rehypePlugins,
@@ -33,13 +32,11 @@ export default ({
})
.trim()
- const code = transform(jsx, {objectAssign: 'Object.assign'}).code
-
const keys = Object.keys(fullScope)
const values = Object.values(fullScope)
// eslint-disable-next-line no-new-func
- const fn = new Function('React', ...keys, `${code}\n\n${suffix}`)
+ const fn = new Function('React', ...keys, `${js}\n\n${suffix}`)
return fn(React, ...values)
}
diff --git a/packages/vue-loader/index.js b/packages/vue-loader/index.js
index becb39b09..397e02472 100644
--- a/packages/vue-loader/index.js
+++ b/packages/vue-loader/index.js
@@ -38,7 +38,8 @@ async function mdxLoader(content) {
result = await mdx(content, {
...options,
skipExport: true,
- mdxFragment: false
+ mdxFragment: false,
+ keepJsx: true
})
} catch (err) {
return callback(err)
diff --git a/packages/vue/test/test.js b/packages/vue/test/test.js
index ac9894122..4f5981fb3 100644
--- a/packages/vue/test/test.js
+++ b/packages/vue/test/test.js
@@ -7,7 +7,11 @@ import {MDXProvider, mdx} from '../src'
const run = async value => {
// Turn the serialized MDX code into serialized JSX…
- const doc = await mdxTransform(value, {skipExport: true, mdxFragment: false})
+ const doc = await mdxTransform(value, {
+ skipExport: true,
+ mdxFragment: false,
+ keepJsx: true
+ })
// …and that into serialized JS.
const {code} = await babelTransform(doc, {
diff --git a/yarn.lock b/yarn.lock
index 87d77cb45..45b420b85 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4985,11 +4985,6 @@ accepts@^1.3.7, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
mime-types "~2.1.24"
negotiator "0.6.2"
-acorn-dynamic-import@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948"
- integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==
-
acorn-globals@^4.1.0, acorn-globals@^4.3.0:
version "4.3.4"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
@@ -5006,7 +5001,7 @@ acorn-globals@^6.0.0:
acorn "^7.1.1"
acorn-walk "^7.1.1"
-acorn-jsx@^5.0.0, acorn-jsx@^5.0.1, acorn-jsx@^5.2.0, acorn-jsx@^5.3.1:
+acorn-jsx@^5.0.0, acorn-jsx@^5.2.0, acorn-jsx@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==
@@ -5026,7 +5021,7 @@ acorn@^5.5.3:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
-acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.7, acorn@^6.1.1, acorn@^6.2.1, acorn@^6.4.1:
+acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.7, acorn@^6.2.1, acorn@^6.4.1:
version "6.4.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
@@ -6590,19 +6585,6 @@ btoa-lite@^1.0.0:
resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc=
-buble-jsx-only@^0.19.8:
- version "0.19.8"
- resolved "https://registry.yarnpkg.com/buble-jsx-only/-/buble-jsx-only-0.19.8.tgz#6e3524aa0f1c523de32496ac9aceb9cc2b493867"
- integrity sha512-7AW19pf7PrKFnGTEDzs6u9+JZqQwM1VnLS19OlqYDhXomtFFknnoQJAPHeg84RMFWAvOhYrG7harizJNwUKJsA==
- dependencies:
- acorn "^6.1.1"
- acorn-dynamic-import "^4.0.0"
- acorn-jsx "^5.0.1"
- chalk "^2.4.2"
- magic-string "^0.25.3"
- minimist "^1.2.0"
- regexpu-core "^4.5.4"
-
buble@0.19.6:
version "0.19.6"
resolved "https://registry.yarnpkg.com/buble/-/buble-0.19.6.tgz#915909b6bd5b11ee03b1c885ec914a8b974d34d3"
@@ -10515,6 +10497,14 @@ estree-util-attach-comments@^1.0.0:
resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-1.0.0.tgz#51d280e458ce85dec0b813bd96d2ce98eae8a3f2"
integrity sha512-sL7dTwFGqzelPlB56lRZY1CC/yDxCe365WQpxNd49ispL40Yv8Tv4SmteGbvZeFwShOOVKfMlo4jrVvwoaMosA==
+estree-util-build-jsx@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-1.0.0.tgz#80df2b0d8fbdfa7e2e7b16c02d007062af2f0ed0"
+ integrity sha512-OVzOP9kjOBO7xiN+A7mMjfJQyIxf+prnohyg1afd3sVHW1GTOY55SfyeKvPO+C0Ej7crP1NG/gFMmowxcKy6kw==
+ dependencies:
+ estree-util-is-identifier-name "^1.0.0"
+ estree-walker "^2.0.0"
+
estree-util-is-identifier-name@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-1.0.0.tgz#3f9b8ae3e9d661858752ce73450f37dca160f029"
@@ -16615,7 +16605,7 @@ magic-string@^0.22.4:
dependencies:
vlq "^0.2.2"
-magic-string@^0.25.1, magic-string@^0.25.2, magic-string@^0.25.3:
+magic-string@^0.25.1, magic-string@^0.25.2:
version "0.25.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
@@ -21821,7 +21811,7 @@ regexpp@^3.0.0, regexpp@^3.1.0:
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
-regexpu-core@^4.2.0, regexpu-core@^4.5.4, regexpu-core@^4.7.1:
+regexpu-core@^4.2.0, regexpu-core@^4.7.1:
version "4.7.1"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6"
integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==