I am creating a VS Code extension that diffs XML based file formats (.pptx, .odt, .xlsx, etc.) To do this I have added React to a VS Code webview. It works by first having webpack bundle the React code separately and then references the bundled file in the VS Code extension, then webapck bundles the extension. I have the React UI working and data for the files to compare is passed from VS Code to React successfully.
The extension works, by unzipping the xml based files then saving copies of the xml parts as files to the storageUri
. Then the file paths are passed to the React component where they are read and a diff tree is created and users can click on an xml part and get its diff with the same part in a different file.
I'm at the point where I need to import join
from path
and read the xml files to compare them, but webpack gives me Uncaught ReferenceError: require is not defined
I know this is a common error and I've read a lot of posts on SO and others about it including: webpack : Uncaught ReferenceError: require is not defined, "require is not defined" Using webpack 2, ReactJS with Webpack: Uncaught ReferenceError: require is not defined, and others, but none of them solved the issue.
The really head scratching part is I only get the error when I user import { join } from 'path';
or any method from path. I can use import { readFile } from 'fs/promises;
and there are no errors and I can use the readFile
method. If I remove the path import there are no errors and everything works, except of course the join
method...
Please let me know if any additional info would be helpful. The full project is on GitHub.
Here is the App.tsx
file that imports path:
import * as React from 'react';
import JSZip from 'jszip';
import { Treebeard } from 'react-treebeard';
import { readFile } from 'fs/promises';
import { join } from 'path';
import './app.css';
const showDiff = ({ vscode, fileData }) => {
const getData = (zip: JSZip, file: string): any => {
// code to format data for Treebeard
};
React.useState(() => {
const leftData = getData(left, leftFileName);
const rightData = getData(right, rightFileName);
setLeftTree({ name: leftFileName, toggled: true, children: leftData });
setRightTree({ name: rightFileName, toggled: true, children: rightData });
});
return (<div className={'container'}>
<div className="file-list-container">
<button onClick={showData}>Click</button>
<Treebeard data={leftTree} onToggle={onToggle} />
</div>
<div className="file-list-container">
<Treebeard data={rightTree} onToggle={onToggle} />
</div>
</div>);
};
export default showDiff;
This is the tsconfig.json
that is used by the React app:
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "node",
"target": "es6",
"outDir": "oxmlDiffViewer",
"lib": [
"es6",
"dom",
"DOM.Iterable"
],
"types": ["node"],
"jsx": "react",
"sourceMap": true,
"rootDir": "..",
"noUnusedLocals": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
},
"exclude": [
"node_modules"
]
}
Here is the tsconfig.json
that the VS Code extension uses:
{
"compilerOptions": {
"jsx": "react",
"module": "commonjs",
"target": "ES2020",
"outDir": "out",
"lib": [
"ES2020",
"DOM"
],
"sourceMap": true,
"rootDir": "src",
"allowSyntheticDefaultImports": true,
"strict": true, /* enable all strict type-checking options */
/* Additional Checks */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
"esModuleInterop": true
},
"exclude": [
"node_modules",
".vscode-test",
"**/view/app/**"
]
}
This is the webpack.config.js
:
const path = require('path');
module.exports = {
entry: {
oxmlDiffViewer: './src/view/app/index.tsx',
},
output: {
path: path.resolve(__dirname, 'oxmlDiffViewer'),
filename: '[name].js',
},
devtool: 'eval-source-map',
resolve: {
extensions: ['.js', '.ts', '.tsx', '.json'],
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
loader: 'ts-loader',
options: {},
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
],
},
target: 'node',
performance: {
hints: false,
},
};
I have been banging my head against the wall with this for 2 days, so any help would be greatly appreciated.