I have a solidJS typescript UI component that I have published to the npm registry.
The project is setup like this:
|-app
|-index.html
|-src
|-index.tsx
|-App.tsx
|-utils
|- ...
|-components
|- ....
|-README.md
|-package.json
|-tsconfig.json
|-vite.config.ts
|-package
|-dist
|-README.md
|-package.json
|- ....
|-src
|- ....
|-README.md
|-package.json
|-tsconfig.json
I have partitioned it so I can build the lib inside the package/ folder and then have it linked within the app/ using the npm link
command.
package.json file looks like this in the package folder:
{
"name": "@melodev/<package-name>",
"version": "...",
"description": "...",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist/"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"clean": "rm -rf dist",
"build": "npm run clean && tsc && cp package.json README.md ./dist"
},
"repository": {
"type": "git",
"url": "git https://github.com/..."
},
"devDependencies": {
"typescript": "^4.7.3"
},
"dependencies": {
"solid-js": "^1.4.7",
"solid-styled-components": "^0.28.4",
"solid-transition-group": "^0.0.10"
},
"keywords": [
// ...
],
"author": "melodev",
"license": "MIT",
"bugs": {
"url": "https://github.com/..."
},
"homepage": "https://github.com/..."
}
Using the npm link
technique works locally. I'm able to use my component.
import Component from "@melodev/<package-name>";
The problem is that importing the package from npm simply won't work! I mean, the package gets installed, the IDE doesn't complain about nothing, but when I run the app...there's only a blank screen and a pretty interesting error message in the console:
Uncaught ReferenceError: React is not defined
But it's not supposed to be a React component!
BTW, my package/tsconfig.json file looks like this so far:
{
"exclude": ["dist", "node_modules"],
"compilerOptions": {
"target": "es6",
"outDir": "./dist",
"lib": ["esnext", "DOM", "DOM.Iterable"],
"declaration": true,
"jsx": "preserve",
"allowJs": true,
"esModuleInterop": true,
"module": "esnext",
"rootDir": "./src",
"moduleResolution": "node",
"sourceMap": true,
"importHelpers": true,
"downlevelIteration": true,
"strict": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noImplicitAny": false,
"skipLibCheck": true,
"skipDefaultLibCheck": true
}
}
Any helpful ideas/resources would be much appreciated. If someone could provide some sort of guidance on publishing SolidJS typescript packages that would be awesome.
CodePudding user response:
If you want to build a package that uses JSX templates, (e.g. <div></div>
) or has a dependency on one that does, (e.g. if you'd like to publish second package that uses this one) you have to build it using rollup and rollup-preset-solid.
If you don't, and you ship only pre-compiled jsx, solid's compiler won't be able to compile the jsx differently for SSR/SPA modes as it builds the app.
You can checkout @solid-primitives/props as an example. Or use this github repo template.
Setting up rollup is very simple, and you probably can just copy paste the setup from package ^
You can enable printInstructions
flag in the rollup preset, to see how the module exports in package.json should look like.
CodePudding user response:
Building upon @thetarnav's answer and also as a resource for developers facing a similar situation I'll let my full solution here.
publishing SolidJS typescript package to npm
1 - clone solid-community/solid-lib-starter
git clone https://github.com/solidjs-community/solid-lib-starter.git
2 - replace the contents inside the src folder with your code
3 - make sure to create an index.tsx
file inside src. Use it file to export your lib's components
export { DatePicker } from './DatePicker';
export { MyComponent } from './MyComponent';
// etc...
4 - make sure that your package.json looks more or less like this
{
"version": "0.1.10",
"name": "{{ package name }}",
"description": "{{ package description }}",
"type": "module",
"files": [
"dist"
],
"main": "dist/esm/index.js",
"module": "dist/esm/index.js",
"types": "dist/types/index.d.ts",
"exports": {
".": {
"solid": "./dist/source/index.jsx",
"import": "./dist/esm/index.js",
"browser": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"node": "./dist/cjs/index.js"
}
},
"scripts": {
"build": "rollup -c",
"prepublishOnly": "pnpm build"
},
"repository": {
"type": "git",
"url": "git https://github.com/{{ git repository }}.git"
},
"keywords": [],
"author": "{{ author name }}",
"license": "MIT",
"homepage": "https://github.com/{{ git repository }}#readme",
"dependencies": {
"solid-js": "^1.1.7",
"solid-styled-components": "^0.28.4",
"solid-transition-group": "^0.0.10"
},
"devDependencies": {
"rollup": "^2.58.0",
"rollup-preset-solid": "^1.0.1",
"typescript": "^4.4.4"
}
}
5 - run pnpm i
to install everything
6 - make sure to have a rollup.config.js
file at the root level
import withSolid from 'rollup-preset-solid';
export default withSolid({
input: "src/index.tsx",
targets: ["esm", "cjs"],
printInstructions: true,
});
OBS: printInstructions: true
will give you a hint on what the paths in your package.json should look like
7 - setup tsconfig.json at the root level. (These settings worked well for me, but there's huge room for customization here)
{
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"declaration": true,
"moduleResolution": "node",
"declarationDir": "./types",
"emitDeclarationOnly": true,
"strict": true,
"jsx": "preserve",
"resolveJsonModule": true,
"noImplicitAny": false
},
"include": ["src"],
"exclude": ["node_modules", "**/__tests__/*"]
}
8 - Don't forget to add a README.md file
9 - run pnpm build
.
This will trigger the build using rollup and should have your dist folder created with four folders inside:
- cjs
- esm
- source
- types
10 - run npm publish --access=public
to have your package published to npm registry