Home > Back-end >  Publish SolidJS Typescript to npm
Publish SolidJS Typescript to npm

Time:07-29

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

  • Related