Closed poke closed 5 years ago
I wish i have seen this issue earlier. Could have saved couple of hours. Thanks for posting. Please fix this issue.
These workarounds seem to work for the most part but since they are all applied to content the dist folder so the changes can get wiped away by NPM.
I am not able to figure out how to apply these workarounds to this repository itself (or rather a fork of it)
@vancerver Yes, these are temporary workarounds to get you running somehow. They are not meant as a real fix. I was hoping that the package maintainers would actually do something about this but in the past 5 months they apparently just ignored this.
As I said, I am unfortunately not involved with this project at all (I’m not even using it myself), so I cannot say what exactly would have to change to make this work – if I could, I would probably have submitted a pull request instead. I expect the changes to be somewhat non-trivial though (packaging usually is).
Microsoft no longer supports this content and will not be responding to bugs or issues. We recommend that you use the newer version, Office UI Fabric, with React as your front-end framework. We are closing this issue; if you still need assistance with Fabric.js, visit Stack Overflow/office-ui-fabric.
The packaging of this module is very broken. There are several issues with it that makes it impossible or at least very difficult to use this module through npm. You can find a more detailed explanation below but there are the following problems with the module:
package.json
.dist/js/fabric.js
creates a local variablefabric
which cannot be consumed by a bundler like webpack.fabric
while the actual module does not contain another wrapped namespace.Steps to reproduce
I reproduced this issue using the
@microsoft/generator-sharepoint
Yeoman generator but these issues exist regardless of that; it just makes it easier to reproduce this quickly.yo @microsoft/generator-sharepoint
. Default options work.npm i
.npm i office-ui-fabric-js --save-dev
Attempt to import anything from this module in the web part’s code (
HelloWorld.ts
), for example:Notice how this will not compile when running
gulp serve
:Problem 1
The
package.json
exposes neither a main entry point nor a typings entry point. This makes consuming the library through npm very difficult since there’s no defined entry point. TypeScript, as an example, is unable to compile imports to theoffice-ui-fabric-js
module because of this.Compare this with for example office-ui-fabric-react, which properly exposes both
main
andtypings
.A simple fix would be to add these properties to the
package.json
:Workaround 1
We augment the installed
package.json
to include entry points, by directly editingnode_modules/office-ui-fabric-js/package.json
to include those two properties.This will fix the import, making the code compile. However, when opening the browser, notice how the
console.log
just logged out an empty object.Problem 2
The
dist/js/fabric.js
that now got bundled does not contain any module exports which Webpack could possible combine here. We can see this by looking at the bundle Webpack creates, i.e.dist/hello-world-web-part.js
. At the bottom, there should be the webpart module with a line like this:But if we look at the webpack module with index
1
in that file, which is thedist/js/fabric.js
, we can see thatmodule
orexports
are never touched by module.Workaround 2
We can fix this again by augmenting the distributed code, for example by adding the following lines at the bottom of
dist/js/fabric.js
:This makes the
console.log
from earlier return an object with thefabric
contents.Problem 3
Let’s attempt to actually “use” the module, let’s actually try to use a button:
console.log(fabric.Button);
will not compile becausefabric
does not containButton
. According to the type hints, we have to either do:or (which effectively means the same though):
If we run this code, we will notice that our browser will throw some cryptic error. This is because
fabric.fabric
isundefined
which we can easily confirm by just doingconsole.log(fabric.fabric)
orconsole.log(fabric)
in the second case.The problem here is that the
fabric.d.ts
exposes a namespacefabric
although thefabric.js
does not.Workaround 3
The proper fix here would probably be to make
fabric.d.ts
not expose a namespace. Namespaces, also known as internal modules, are usually not needed since physical files already create (external) modules which is enough of a namespacing construct.The easier workaround is to adjust the
dist/js/fabric.js
again to actually expose that namespace:Note that this does not expose the other “visible” members of the module that are exposed by the
fabric.d.ts
. For exampleCLOSE_BUTTON_CLASS
which is still just a local variable infabric.js
that is thrown away.In addition, if you look at the
dist/js/fabric.js
, you can actually see thatvar fabric
appears there a lot of times. So this effectively declares local variables over and over again which might already be a sign that the dist bundling for this package is simply not how it is supposed to be. Ideally, there should only be a single export.I would expect this to get a lot better if the component modules were actual modules instead of weird things that each declare a namespace.
That way, it would likely also make it possible to consume the module sources without having to consume the bundle. However, I am not involved enough with this to understand how the non-TS files come into play here. Actually, a colleague asked me for help on this which made me look into the bundling process here. But I really hope that this description does help to improve the situation for consumers of the library here.