From 07a89708d4ed19cbee25cf6d6d4bf7c3300df926 Mon Sep 17 00:00:00 2001 From: theluckystrike <51033404+theluckystrike@users.noreply.github.com> Date: Sat, 3 Oct 2026 13:00:57 +0700 Subject: [PATCH] fix: allow importing the bundle without a DOM The webpack build picked the browser build of react-textarea-autosize, which reads document at import time. Bundle its default build instead, which checks for document first. Fixes #149 Co-Authored-By: Claude Opus 5.5 --- test/tests/js/Bundle-test.js | 49 ++++++++++++++++++++++++++++++++++++ webpack/webpack.config.js | 7 +++++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 test/tests/js/Bundle-test.js diff --git a/test/tests/js/Bundle-test.js b/test/tests/js/Bundle-test.js new file mode 100644 index 0000000..8a30c45 --- /dev/null +++ b/test/tests/js/Bundle-test.js @@ -0,0 +1,49 @@ +import fs from 'fs' +import os from 'os' +import path from 'path' +import vm from 'vm' +import webpack from 'webpack' +import { expect } from 'chai' + +import webpackConfig from './../../../webpack/webpack.config' + +function build (outputPath) { + const config = { + ...webpackConfig, + output: { ...webpackConfig.output, path: outputPath }, + optimization: { minimize: false } + } + + return new Promise((resolve, reject) => { + webpack(config, (error, stats) => { + if (error) return reject(error) + if (stats.hasErrors()) { return reject(new Error(stats.toString('errors-only'))) } + resolve(path.join(outputPath, config.output.filename)) + }) + }) +} + +describe('dist bundle', function () { + this.timeout(60000) + + it('can be imported without a DOM (SSR)', async function () { + const outputPath = fs.mkdtempSync(path.join(os.tmpdir(), 'rjv-bundle-')) + try { + const file = await build(outputPath) + const code = fs.readFileSync(file, 'utf8') + const module = { exports: {} } + // a fresh context has no `window` or `document`, like Node during SSR + const context = vm.createContext({ + module, + exports: module.exports, + require + }) + + vm.runInContext(code, context, { filename: file }) + + expect(module.exports.default).to.be.a('function') + } finally { + fs.rmSync(outputPath, { recursive: true, force: true }) + } + }) +}) diff --git a/webpack/webpack.config.js b/webpack/webpack.config.js index 4bf03e5..210cbcc 100644 --- a/webpack/webpack.config.js +++ b/webpack/webpack.config.js @@ -37,7 +37,12 @@ const config = { }, plugins: [], resolve: { - extensions: ['.js', '.json', '.css', '.scss'] + extensions: ['.js', '.json', '.css', '.scss'], + alias: { + // The browser build reads `document` on import, which breaks SSR. + // The default build checks for `document` first, so bundle that one. + 'react-textarea-autosize$': require.resolve('react-textarea-autosize') + } }, module: { rules: [