-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor TypeScript typings to use ES style exports #5016
Conversation
Codecov Report
@@ Coverage Diff @@
## dev #5016 +/- ##
========================================
+ Coverage 99.3% 100% +0.69%
========================================
Files 92 86 -6
Lines 3737 3488 -249
========================================
- Hits 3711 3488 -223
+ Misses 26 0 -26
Continue to review full report at Codecov.
|
@ktsn @HerringtonDarkholme this will likely also affect |
I need some local test here. Please kindly wait a moment. I guess this typing change will be fine for webpack users. |
It seems to break some TypeScript libraries that directly depends on Vue. They need to be updated and also the updated library does not seem to be compatible with old (commonjs style) Vue. It's because TypeScript does not interop ESModule and CommonJS at all (as same as export). // commonjs style import
import Vue = require('vue')
// will be compiled to ...
var Vue = require('vue') // esmodule style import
import Vue from 'vue'
// will be compiled to ...
var Vue = require('vue').default |
@ktsn I think we will need to break something for consistent import style across TS/JS. But we should consider what part should we break. Or what should we support. |
What exactly is the runtime semantics? Vue is a CJS importable entity, but it's written as ES modules, so how are you transforming your code right now? Also, what is the original source of breakage for TypeScript users? |
Hi @DanielRosenwasser . Vue now outputs a es module file for webpack/rollup users. So tree shaking will work. And Vue has supported commonjs output file as well. These two versions are compiled into two files by two different rollup configs. For node/browserfiy users, they use vue.common.js, specified by For webpack/rollup users, they use vue.esm.js, specified by Library authors will also want to support both ESM and commonjs. Babel/webpack has compatbile require builtin. If an author writes library in Babel, Babel will take care of how Vue is imported. So library users can freely use ESM/commonjs and the author will need simply write one However, TypeScript does not have builtin compatible library. An author must choose one style |
After some thoughts, maybe there is something that can be done in webpack 2. Right now the problem is that with the import Vue from 'vue' // <- gets the default export from the ESM build
const Vue = require('vue') // <- returns { __esModule: true, default: Vue } IMO the /cc @TheLarkInn |
And for now, I think the best path forward is recommend Vue + TS users to start using |
Let me summarize some findings. Sorted by effort required.
I'd rather argue the break in case 3 is sooner or later: e.g. by node-esm spec. (My speculation is not many users are using browserify + ts + vue, but if they do use this combo at least babel will come to rescue.) |
FYI, updated TypeScript usage docs: https://vuejs.org/v2/guide/typescript.html |
The problem is that TypeScript doesn't actually synthesize the default export for a CJS module - this will type-check just fine, but will not work at runtime. |
@DanielRosenwasser for webpack 1 yes the user would have to use babel for interop. Webpack 2 uses the ES module build automatically so the semantics align. Webpack 1 is considered deprecated and upgrading to 2 doesn't require much effort, so we'd prefer sticking to es modules in all cases. |
Sure - it'd be AMD and Webpack 1 that would have problems though. I don't know how many people are using the former, but I'll take your word on the latter. I see you already added |
@DanielRosenwasser while we are on this topic - is it possible to allow packages to configure a different d.ts for different module formats? Similar to how the convention for webpack 2 is using "module" for ES modules build and "main" for CommonJS build, it would be helpful to have something like maybe "module-types" for d.ts with es style exports... or maybe something that allows the user to manually specify the d.ts for a specific module in tsconfig.json, like "resolve.alias" in webpack. |
This sort of works if you use path-mapping (using the |
Closing in favor of #5887. |
This PR will change Vue's TS typings to use ES-style exports so that it works better with the new ES module build + webpack 2 combo.
So instead of:
TS users should now use:
...which is consistent with recommended plain ES usage.
This is technically a breaking change, but since we've already unintentionally caused a breaking change for webpack 2 + TS users, we should probably just fully migrate to ES-based exports to avoid more breakage in the future.
Related: