Skip to content
This repository was archived by the owner on Nov 20, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ jobs:
with:
node-version: ${{ matrix.node }}

- run: yarn install
- run: yarn install --ignore-engines # Webpack 5 does not support Node v8, but we still do for Webpack 4

- run: yarn ${{ matrix.test-command }}
192 changes: 108 additions & 84 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,105 +7,129 @@ import {
SourceMapsPathDescriptor,
} from '@sentry/cli';

export interface SentryCliPluginOptions
extends Pick<
SentryCliOptions,
'url' | 'authToken' | 'org' | 'project' | 'vscRemote' | 'dist' | 'silent'
>,
Pick<
SentryCliUploadSourceMapsOptions,
| 'ignoreFile'
| 'rewrite'
| 'sourceMapReference'
| 'stripPrefix'
| 'stripCommonPrefix'
| 'validate'
| 'urlPrefix'
| 'urlSuffix'
| 'ext'
> {
/**
* Filepaths to scan recursively for source and source map files
*/
include:
| string
| SourceMapsPathDescriptor
| Array<string | SourceMapsPathDescriptor>;
declare namespace SentryCliPlugin {
export interface SentryCliPluginOptions
extends Pick<
SentryCliOptions,
| 'url'
| 'authToken'
| 'org'
| 'project'
| 'vscRemote'
| 'dist'
| 'silent'
>,
Pick<
SentryCliUploadSourceMapsOptions,
| 'ignoreFile'
| 'rewrite'
| 'sourceMapReference'
| 'stripPrefix'
| 'stripCommonPrefix'
| 'validate'
| 'urlPrefix'
| 'urlSuffix'
| 'ext'
> {
/**
* Filepaths to scan recursively for source and source map files
*/
include:
| string
| SourceMapsPathDescriptor
| Array<string | SourceMapsPathDescriptor>;

/**
* Filepaths to ignore when scanning for sources and source maps
*/
ignore?: string | Array<string>;
/**
* Filepaths to ignore when scanning for sources and source maps
*/
ignore?: string | Array<string>;

/**
* Unique name of a release, must be a string, should uniquely identify your release,
* defaults to sentry-cli releases propose-version command which should always return the correct version
* (requires access to git CLI and root directory to be a valid repository).
*/
release?: string;
/**
* Unique name of a release, must be a string, should uniquely identify your release,
* defaults to sentry-cli releases propose-version command which should always return the correct version
* (requires access to git CLI and root directory to be a valid repository).
*/
release?: string;

/**
* A filter for entry points that should be processed.
* By default, the release will be injected into all entry points.
*/
entries?: string[] | RegExp | ((key: string) => boolean);
/**
* A filter for entry points that should be processed.
* By default, the release will be injected into all entry points.
*/
entries?: string[] | RegExp | ((key: string) => boolean);

/**
* Path to Sentry CLI config properties, as described in https://docs.sentry.io/learn/cli/configuration/#properties-files.
* By default, the config file is looked for upwards from the current path and defaults from ~/.sentryclirc are always loaded.
*/
configFile?: string;
/**
* Path to Sentry CLI config properties, as described in https://docs.sentry.io/learn/cli/configuration/#properties-files.
* By default, the config file is looked for upwards from the current path and defaults from ~/.sentryclirc are always loaded.
*/
configFile?: string;

/**
* Determines whether processed release should be automatically finalized after artifacts upload.
* Defaults to `true`.
*/
finalize?: boolean;
/**
* Determines whether processed release should be automatically finalized after artifacts upload.
* Defaults to `true`.
*/
finalize?: boolean;

/**
* Determines whether plugin should be applied not more than once during whole webpack run.
* Useful when the process is performing multiple builds using the same config.
* Defaults to `false`.
*/
runOnce?: boolean;
/**
* Determines whether plugin should be applied not more than once during whole webpack run.
* Useful when the process is performing multiple builds using the same config.
* Defaults to `false`.
*/
runOnce?: boolean;

/**
* Attempts a dry run (useful for dev environments).
*/
dryRun?: boolean;
/**
* Attempts a dry run (useful for dev environments).
*/
dryRun?: boolean;

/**
* Print some useful debug information.
*/
debug?: boolean;
/**
* Print some useful debug information.
*/
debug?: boolean;

/**
* If true, will remove all previously uploaded artifacts from the configured release.
*/
cleanArtifacts?: boolean;
/**
* If true, will remove all previously uploaded artifacts from the configured release.
*/
cleanArtifacts?: boolean;

/**
* when Cli error occurs, plugin calls this function.
* webpack compilation failure can be chosen by calling invokeErr callback or not.
* defaults to `(err, invokeErr) => { invokeErr() }`
*/
errorHandler?: (err: Error, invokeErr: () => void, compilation: Compilation) => void;
/**
* when Cli error occurs, plugin calls this function.
* webpack compilation failure can be chosen by calling invokeErr callback or not.
* defaults to `(err, invokeErr) => { invokeErr() }`
*/
errorHandler?: (
err: Error,
invokeErr: () => void,
compilation: Compilation
) => void;

/**
* Adds commits to sentry
*/
setCommits?: SentryCliCommitsOptions;
/**
* Adds commits to sentry
*/
setCommits?: SentryCliCommitsOptions;

/**
* Creates a new release deployment
*/
deploy?: SentryCliNewDeployOptions;
/**
* Creates a new release deployment
*/
deploy?: SentryCliNewDeployOptions;
}
}

declare class SentryCliPlugin implements WebpackPluginInstance {
options: SentryCliPluginOptions;
constructor(options: SentryCliPluginOptions);
options: SentryCliPlugin.SentryCliPluginOptions;
constructor(options: SentryCliPlugin.SentryCliPluginOptions);
apply(compiler: Compiler): void;
}

export default SentryCliPlugin;
// We need to use this older format (over `export default SentryCliPlugin`)
// because we don't want people using the plugin in their TS projects to be
// forced to set `esmoduleinterop` to `true`, which the newer syntax requires.
// See
// https://github.com/microsoft/TypeScript-Website/blob/6a36b3137182084c76cdf133c812fe3a5626dbf0/packages/documentation/copy/en/declaration-files/templates/module.d.ts.md#L95-L106
// (linking to the docs in their raw form on GH rather than on the TS docs site
// in case the docs site ever moves things around).
//
// Note that with this older format, no other top-level exports can exist, which
// is why the exported interface above is wrapped in a namespace. See the
// example in the above link and
// https://github.com/microsoft/TypeScript-Website/blob/6a36b3137182084c76cdf133c812fe3a5626dbf0/packages/documentation/copy/en/declaration-files/templates/module.d.ts.md#L195-L214.
export = SentryCliPlugin;
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@sentry/cli": "^1.68.0"
},
"devDependencies": {
"@types/webpack": "^4.0.0 || ^5.0.0",
"codecov": "^3.5.0",
"eslint": "^5.16.0",
"eslint-config-airbnb-base": "^13.1.0",
Expand All @@ -32,6 +33,9 @@
"prettier-check": "^2.0.0",
"webpack": "^4.39.3"
},
"peerDependencies": {
"@types/webpack": "^4.0.0 || ^5.0.0"
},
Comment on lines +36 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this. This way we will make everyone install it, even when they are not using TypeScript. Otherwise, we'll warn every time they don't.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning is fine IMO. But, when does one install the webpack plugin and not webpack?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never, but those are types, not webpack itself.

Copy link
Member Author

@lobsterkatie lobsterkatie Oct 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I debated about that. I can't believe we put a man on the moon more than half a century ago and still haven't solved this problem. Either we:

  • make it a hard dependency ( which is what the TS docs would have us do), and plain JS people install a package they don't need, or

  • make it a peer dependency, and plain JS people get warnings which don't apply to them, or

  • make it neither, and TS people get yelled at by their linter and/or compiler unless they just happen to already have the relevant types installed.

Which is the least bad, do we think?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one is a no-go for me, and I rather the third over the second although not strongly opinionated against the second one.

  • Why should JS people get warnings related to TS?
  • TS people know they sometimes need to install additional modules for the types, so this shouldn't be a big deal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also go with 3rd. If you are using TypeScript and Webpack, there's 99,99% chance that you already have those types installed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TS people know they sometimes need to install additional modules for the types, so this shouldn't be a big deal.

Yeah, but that's generally for their own dependencies, not transitive ones. I agree it's not the world's biggest blocker, and people will figure it out, so in this case I'm happy to go with option 3, especially since you're right, @kamilogorek, it's not like webpack is obscure and at least some folks will already have the types. (I'm less convinced it's everyone, though. If you're using our nextjs SDK and don't have any custom webpack config other than what you pass to our plugin, there's no reason you'd already have them.) So I can pull it.

As a general principle, though, and given just how popular TS is, it's still just amazing to me that npm/yarn haven't adapted to what has to be a pretty common situation/problem.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general principle, though, and given just how popular TS is, it's still just amazing to me that npm/yarn haven't adapted to what has to be a pretty common situation/problem.

Not sure this is only an npm/yarn thing, but also from the npm registry? But yes, there should be a solution to this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is only an npm/yarn thing, but also from the npm registry?

Not sure what you mean.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The npm registry is npmjs.com, and then the npm tool which you use to manage the modules in the registry. Anyways, I haven't dived into the registry and I don't know where the solution should be coming from, just giving my thoughts.

"scripts": {
"lint": "run-s lint:prettier lint:eslint",
"lint:prettier": "prettier-check 'src/**/*.js'",
Expand Down
19 changes: 19 additions & 0 deletions src/cjs.js
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
module.exports = require('./index').default;

// The assignment to `default` below saves us from having to use
// `esModuleInterop` (which then would force our users to set the same option),
// by manually doing the one part of `esModuleInterop`'s job we actually need.
//
// (In order to avoid a breaking change, we need to stick with default-exporting
// `SentryCliPlugin`. This means that if we want to use ES6 imports (in our own
// use of the plugin), our options are:
//
// `import * as x from y`,
// `import x from y`, and
// `import {default as x} from y`.
//
// If we use the first option, it correctly pulls in the above `module.exports`
// value, but it treats it as a namespace, not a class, and therefore refuses to
// let it be used with `new`. If we use either of the other two, it looks for
// `module.exports.default`, which will be undefined unless either we do (or
// `esModuleInterop` does) the below.)
module.exports.default = module.exports;
Loading