Coder Social home page Coder Social logo

publint's Introduction

publint's People

Contributors

bluwy avatar btea avatar dependabot[bot] avatar jungzl avatar lachlancollins avatar nvie avatar sapphi-red avatar wooorm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

publint's Issues

ignore exports import.development

"exports": {
    ".": {
        "import": {
            "default": "./dist/es"
        }
    },
    "./*": {
        "import": {
            // !: should be ignore
            "development": "./src/*",
            "default": "./dist/es/*"
        }
    }
}

error1:

❯ publint
xxx lint results:
Warnings:
1. pkg.exports["./*"].import.development matches ./src/base/create-component.js and is written in ESM, but is interpreted as CJS. Consider using the .mjs extension, e.g. ./src/base/create-component.mjs

error2:

1. pkg.exports["./*"].import.development is ./src/* but the file is not published. Is it specified in pkg.files?

@bluwy

Print a link to package.json while displaying errors.

publint prints errors in package.json in the format pkg.exports["./path/to/exports"].property has error X. A minor quality of life improvement would be printing the package.json path with line numbers such that you can Ctrl+Click to the error in VS Code and friends.

Fix a11y warnings in NpmSearchInput.svelte

Svelte brings up new a11y warnings for that component, apparently I was using some ARIA attributes wrong 😬

Viewable via VSCode, or when running the site in dev mode.

Warning as error in CLI mode

Having the ability to mark warnings as errors when running publint through the CLI might be pretty useful. Some lint rules such as types not being properly defined via exports come as warnings and being able to promote them to errors (not just them, but just say we forbid errors and warnings) would be great.

I was thinking about some flags such as --warning-as-error or --max-warnings num (see https://eslint.org/docs/latest/use/command-line-interface#max-warnings).

Rule: validate dependency duplication

It would be great if publint could check if some dependencies where listed multiple times across dependencies + devDependencies and dependencies + peerDependencies.

I can't actually find any good resource that explains if this is valid or not, but my intuition tells me that it doesn't make sense to have the same package listed multiple times across the different types of dependencies. I might very well be forgetting some use cases though.

  1. Why would you have typescript both as a dependency and a dev dependency? If it's a dependency then it will already be there during development, meaning that the devDependency is unnecessary
  2. Why would you have typescript both as a dependency and a peer dependency? If it's a dependency then why would you need peers to add the dependency as well?
  3. It makes perfect sense to have typescript as a peer dependency and a dev dependency, so it's there during development, but not during production. You could even argue that there should be a rule that checks if all peer dependencies are listed as dev dependencies? (I might be too simple minded here)

The reason this comes up for me, is because we're discussing if this is valid or not:

{
  "dependencies": {
    "typescript": "^4.9.0"
  },
  "devDependencies": {
  },
  "peerDependencies": {
    "typescript": "^4.0.0 || ^5.0.0"
  },
  "peerDependenciesMeta": {
    "typescript": {
      "optional": true
    }
  },

}

One party thinks this means "if TypeScript is supplied as a peer that's great, use that. If not, let the package manager know that it should install it for us", while I believe that this means "always install TypeScript as a dependency, it's an optional peer dependency too but that will never be used anyway".

Maybe there are use cases for having the same package listed with different versions, but I can't personally think of any.

No "exports" main defined

Error occurs when using @vite/release-script node version 18; Also, the project is not type:module

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in E:\workspace\element-plus-xx\node_modules.pnpm@[email protected]\node_modules\publint\package.json

Consider rename printMessage API

printMessage returns the string, it sounds more like formatMessage instead of actually printing. Maybe considering a rename or adding a new API formatMessage and then deprecate printMessage in next big release

pnpm support

vite/packages/vite$ pnpx publint deps
pnpm: Command failed with exit code 1: publint deps
    at makeError (~/.local/share/pnpm/global/5/.pnpm/[email protected]/node_modules/pnpm/dist/pnpm.cjs:23105:17)
    at handlePromise (~/.local/share/pnpm/global/5/.pnpm/[email protected]/node_modules/pnpm/dist/pnpm.cjs:23676:33)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Object.handler [as dlx] (~/.local/share/pnpm/global/5/.pnpm/[email protected]/node_modules/pnpm/dist/pnpm.cjs:215806:7)
    at async ~/.local/share/pnpm/global/5/.pnpm/[email protected]/node_modules/pnpm/dist/pnpm.cjs:223397:21
    at async main (~/.local/share/pnpm/global/5/.pnpm/[email protected]/node_modules/pnpm/dist/pnpm.cjs:223366:34)
    at async runPnpm (~/.local/share/pnpm/global/5/.pnpm/[email protected]/node_modules/pnpm/dist/pnpm.cjs:223596:5)
    at async ~/.local/share/pnpm/global/5/.pnpm/[email protected]/node_modules/pnpm/dist/pnpm.cjs:223588:7

Feature: add select to switch the version

Sometimes there is a problem in the new version, but the previous version is no problem, add a select to quickly switch the version to easily locate which version is the problem.

I can try to create a PR if you think it works.。

Show the final resolved path when `exports` and `browser` field is both used

If both exports field and browser field is used, browser field will map the result of exports field to another path.
For example, if the following package.json and a worker condition is used, . will resolve to ./foo.browser2.js for most bundlers (except esbuild).

{
  "browser": {
    "./foo.browser.js": "./foo.browser2.js"
  },
  "exports": {
    ".": {
      "worker": "./foo.browser.js"
    }
  }
}

See https://github.com/patdx/package-exports-test.

I believe this is really confusing and it's better to avoid relying on this behavior if it's possible.
That said, I haven't come up with a rewriting procedure that can be done universally. (other than duplicating the file)

Maybe we can give a warning if browser field maps the path of exports field? But I don't know if it's possible to avoid in all cases.
So I think showing the final resolved path is a good alternative.

related: solidjs/solid-start#263, vitejs/vite#10323, Andarist/react-textarea-autosize#385

pkg.main is index.js but the file does not exist.

I use the new SvelteKit packaging and when I run publint, I get the following error even though I have the dist/index.js file.

> svelte-kit sync && svelte-package && publint

src/lib -> dist
svelte-awesome-icons lint results:
Errors:
1. pkg.main is index.js but the file does not exist.

What could be the reasons?

Ensure exports match glob

Cool package! thanks for publishing!

Given this dir structure in a package root, I want to ensure that exports includes all of those files.

elements
├── pf-accordion
│   ├── pf-accordion-header.js
│   ├── pf-accordion.js
│   └── pf-accordion-panel.js
├── pf-avatar
│   └── pf-avatar.js
├── pf-badge
│   └── pf-badge.js
└── pf-tooltip
    └── pf-tooltip.js

20 directories, 26 files

So linting with an option like exportGlobs: ['elements/*/pf-*.js'],

This "exports" field should fail

{ '.': './pfe.js' }

and this one should pass:

{
  '.': './pfe.js',
  './pf-accordion/pf-accordion-header.js': './pf-accordion/pf-accordion-header.js',
  './pf-accordion/pf-accordion-panel.js': './pf-accordion/pf-accordion-panel.js',
  './pf-accordion/pf-accordion.js': './pf-accordion/pf-accordion.js',
  './pf-avatar/pf-avatar.js': './pf-avatar/pf-avatar.js',
  './pf-badge/pf-badge.js': './pf-badge/pf-badge.js',
  './pf-tooltip/pf-tooltip.js': './pf-tooltip/pf-tooltip.js'
}

Suggest remove `main` and `module` if have `exports`

The exports field supersedes other mainFields, if the tooling supports the exports field.

exports is supported since:

  • Node.js v12.7 (Release: 2019-07-23) (history)
    • Around the same time when ESM support is stabilized (history)
    • Earliest ESM support is v8.5, but adoption could be considered low as it was experimental until v12.20
  • Webpack 5 (Release: 2020-10-10)
    • Webpack 4 does not support exports, which is what the majority still uses.
  • @rollupjs/plugin-node-resolve v11.1 (Release: 2021-01-15)
  • Parcel 2.9.0 (Release: 2023-05-26) - parcel-bundler/parcel#4155
  • Other recent tooling should support this by default.

exports is still not supported by:


Given the state of support, perhaps we have to wait a bit longer. Because many packages will have both main/module and exports, and suggesting this would be a huge breaking change without much benefit.

I think there's now enough support to start providing this suggestion. There's still the concern that it's totally fine to keep using the main fields just in case, but I think this is a good nudge towards a single way to export things, and will help simplify library publishing in the future.

This suggestion is initially brought up in #21.

Crawl imports

Crawling imports can enable linting more files that may have exports issues, e.g. a .mjs file imports an ESM .js file but is treated as CJS. This would catch errors for sveltejs/kit#8267.

This would also enable catching packages that uses nodejs builtin modules for browser exports. (NOTE: We may need a setting to tell if this package is from node or browser by default)

A simple way to lint all dependencies

Currently npx publint [dir] only supports linting a single directory. It would be convenient to have a command like npx publint deps to lint all deps quickly.

Other requirements:

  • Should pretty print multiple packages results in the CLI (Alphabetical)
  • A --filter argument will likely be needed
  • Should work in yarn and Deno resolutions

Other ideas:

  • Support uploading the package.json on https://publint.dev
  • Cache previous results with --cache argument

Add hints for types export

Exporting types is hard when you have multiple entrypoints. If the consumer's TypeScript configuration supports node16, the types condition should work splendidly. If not, there's a couple ways around it.

1. Map export path to actual files

If you have an export like my-lib/subpath, make sure you have a /subpath.d.ts file. Likewise for my-lib/really/deep/subpath, create a /really/deep/subpath.d.ts file.

2. Declare module

If your package has an ambient file, you can use declare module to achieve the same without needing to create new files. The downside though is that all types are in a single file, and the user needs to understand how ambient types work.

declare module 'my-lib/subpath' {
  export const hello: string
}

Because it's an ambient file, you will need the user to do /// <reference types="my-lib" /> in their own ambient file.

// src/global.d.ts (common names: env, ambient)
/// <reference types="my-lib" />`

It's not recommended to add to compilerOptions.types as that overrides types search. (TODO: needs more explanation)

Ambient files must also be script files, not module files. https://www.typescriptlang.org/docs/handbook/modules.html

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).


Ideally we want to make sure types work in either node16 or not, and we give a hint on the first approach. The second approach is valid and publint needs to check patterns like these to not incorrectly give the hint.

[Feature Request] Add a way to lint locally uploaded build artifacts

By enabling the upload of arbitrary local build artifacts, those packages that are otherwise published privately could also be linted. I realize that this directly conflicts with the name of the project but I think it would be a very useful feature.
Thank you, awesome project anyway!

Consider using browser exports condition over browser field

The browser field could be used to replace nodejs files to browser-safe alternative files, but the browser export condition also covers this area, albeit both have different strategies.

It might be worth recommending using the browser exports condition instead in all cases.

Not warning about missing types field

Take the following package.json

{
	"exports": {
		".": {
			"require": "./dist/index.cjs",
			"import": "./dist/index.js"
		}
	},
}

It didn't warn about a missing top level types field or a missing types field in the exports map, it did however warn about a missing types field in the exports map when adding a top level types field

Erroneous recommendation for `types` exports

Hi!

Linting my project with publint raises a warning: the linter recommend adding a types exports.

However, if I follow this recommendation, this creates an issue according to a linter of TypeScript team member: "Types are ESM, but implementation is CJS.". The only way to correctly export types when dual publishing cjs and esm is to remove the types exports and adding .d.cts / .d.ts / .d.mts along with corresponding files.

I understand the reasoning behind requiring types exports.
publint could detect dual publishing and then, in this particular case, recommend removing types exports.

Support glob paths in CLI

Support npx publint ./packages/* to lint all directories at once, and only those that have a package.json.

Make sure this works with --deps too, which would create another dimension when linting. (N directories x N deps)

Possibly invalid warning with dual esm/cjs types

I may be wrong and this is necessary, but I've seen the second setup in a popular open source library - is it invalid or not?

"All good!"

  "types": "./src/types.d.ts",
  "exports": {
    "./package.json": "./package.json",
    ".": {
      "import": {
        "types": "./src/types.d.mts",
        "default": "./dist/file.mjs"
      },
      "module": {
        "types": "./src/types.d.ts",
        "default": "./dist/file.esm.js"
      },
      "default": {
        "types": "./src/types.d.ts",
        "default": "./dist/file.umd.js"
      }
    }
  },

Warning

  1. pkg.exports["."].types types is an invalid format when resolving with the "import" condition. Consider splitting out two types conditions for import and require, and use the .mts extension, e.g. pkg.exports["."].import.types: "./src/types.d.mts"
  "types": "./src/types.d.ts",
  "exports": {
    "./package.json": "./package.json",
    ".": {
      "types": "./src/types.d.ts",
      "import": {
        "types": "./src/types.d.mts",
        "default": "./dist/file.mjs"
      },
      "module": "./dist/file.esm.js",
      "default": "./dist/file.umd.js"
    }
  },

Lint environment

When linting a package, the package could be meant for browsers only, or nodejs only. This isn't statically anaylzable (though possibly inferred), so it may need a new configuration option to specify the intended environment.

This would make things less "automatic" but is needed for correctness. I'm not sure yet how this would work with npx publint deps and the site.

printMessage API documentation

Then printMessage requires two arguments, message and package json, but document is missing pkg argument.

Another is printMessage returns the string, it sounds more like formatMessage instead of actually printing. Maybe considering a rename or adding a new API formatMessage and then deprecate printMessage in next big release

False positives makes esbuild to fail?

I found that you MUST prefix the paths with ./ or they'll fail with esbuild, not sure if this happens with other bundlers or environments, e.g.

"exports": {
  ".": {
    "import": "dist/somedom.mjs",
    "require": "dist/somedom.js",
    "browser": "dist/somedom.umd.js"
  },
  "./ssr": {
    "import": "dist/index.ssr.mjs",
    "require": "dist/index.ssr.js"
  }
}

This configuration yields The package target "dist/somedom.mjs" is invalid if consumed on other modules.

Once I prefixed the paths to ./dist then it worked without issues.

I think this is an issue, because I ran publint and it said it was correct, which was not true.

So much thanks for this amazing tool, see you!

Update npm-packlist

npm v9 introduced a breaking change to npm-packlist (release notes). However yarn v3 and pnpm v7 have not adopted this yet.

This issue tracks when yarn and pnpm start moving towards the new pack logic before we update it.

Ignore extension format check for module exports condition

The "module" exports condition can use any extension regardless of the code format (ESM or CJS) as nodejs ignores the condition by default. Similarly to the "exports" field, it's used by bundlers only so the extension restriction doesn't apply here.

Missing types entry in exports

I don't know if it happens often, but lightningcss is green on publint but fails to check with TS 5 bundler mode:

TS7016: Could not find a declaration file for module 'lightningcss'. '/Users/arnaud/git/rds/node_modules/lightningcss/node/index.mjs' implicitly has an 'any' type.
   There are types at '/Users/arnaud/git/rds/node_modules/lightningcss/node/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'lightningcss' library may need to update its package.json or typings.

Re: parcel-bundler/lightningcss#448

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.