Closed dangviettuan closed 3 months ago
After a week try many solutions I found a way to publish a library with all dependencies.
workspace.json
"build": {
"builder": "@nrwl/web:package",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/<YOUR LIB IMPORT PATH>",
"tsConfig": "libs/<YOUR PACKAGE DIRECTORY>/tsconfig.lib.json",
"project": "libs/<YOUR PACKAGE DIRECTORY>/package.json",
"entryFile": "libs/<YOUR PACKAGE DIRECTORY>/src/index.ts",
"external": [<IF YOU HAVE ANY EXTERAL LIBS WANT TO IGNORE FROM BUNDLE (react, react-dom)>],
"babelConfig": "@nrwl/react/plugins/bundle-babel", (Optional: If you lib is React Lib)
"rollupConfig": "@nrwl/react/plugins/bundle-rollup", (Optional: If you lib is React Lib)
"assets": [
{
"glob": "README.md",
"input": ".",
"output": "."
}
]
}
},```
paths
in tsconfig.base.json
file same with "paths": {
"@myorg/my-awesome-lib": ["libs/ui/awsome-button/src/index.ts"],
.....
},
--with-deps
flag. Rebuild you library with custom rollup config
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const builtins = require('rollup-plugin-node-builtins');
const resolve = require('@rollup/plugin-node-resolve');
const fileExtensions = ['.js', '.jsx', '.ts', '.tsx'];
function getRollupOptions(options) {
const extraGlobals = {
// <YOUR EXTRAGLOBALS NAMES>
// Example:
'react-dom': 'ReactDOM',
'styled-components': 'styled',
'@emotion/core': 'emotionCore',
};
if (Array.isArray(options.output)) {
options.output.forEach((o) => {
o.globals = Object.assign(Object.assign({}, o.globals), extraGlobals);
});
} else {
options.output.globals = Object.assign(
Object.assign({}, options.output.globals),
extraGlobals
);
}
options.plugins.push(
resolve.nodeResolve({
preferBuiltins: true,
extensions: fileExtensions,
moduleDirectories: ['dist/libs', 'node_modules'], // IMPORTANT
})
);
options.plugins.push(builtins());
options.external = [
// YOUR EXTERNAL LIBS (Libs you don't want to bundle)
// Example:
'react',
'react-is'
];
return options;
}
module.exports = getRollupOptions;
dependencies
or peerDependencies
. You can select by add flag buildableProjectDepsInPackageJsonType=
dependencies
or peerDependencies
to buid command.--no-extractCss
to the build command. I don't know why my buildable library exported to 2 CSS files but when bundle my publishable library CSS files not included. So embed CSS inside JS is my choice.module augmentation
to override a third-party interface. After the bundle, an error occurred because of undefined
property. To fix it I remove third-party library from the external
list to bundle it with my library.I find this to be a workaround for something that I would expect to exist out of the box. @dangviettuan why have you closed this issue?
@nemanjamilosavljevic-newtron Exactly, That is my workaround solution.
I read all issues relate to publishing a lib in repository issues and in the Slack channel but there is no answer so I decided to read, understand Nx source code, and finished with the custom Rollup build script.
I think Nx have done their job. Because we are building publishable libs and used it locally. The import statement can be treated as an external package.
Although it still has some issues with this approach I think it relates to different issues like export package.json dependencies.
Do you have any suggestion? Should we re-open this issue?
I also think that the framework is super nice!
From the slack channel I've learned that all libraries in question should be publishable, however, I've tried that approach, and it hasn't worked. What I would love is to hear the official solution to this problem.
Ya. Because I just want to publish only one package instead of many packages and take time to manage and deploy them so I decide to use custom Rollup Script. What is your current problem with publishable libs?
Btw. I will reopen this issue.
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! ๐
Comment to keep this issue open
@dangviettuan @nemonemi Commenting to keep this open. definitely doesn't feel like a feature we need to hack together to work as expected.
Hi @vsavkin Would this issue be fixed in the upcoming versions?
I struggled a lot with this over the last few days trying many many things, I have some core helpers and types which I wanted to include in a publishable UMD app. In the end, for me, it was very simple to bypass the 'rootDir' is expected to contain all source files.
error.
Maybe this helps some of you, I added the helper and the types like normal.
import { colorSchemesFindHexById } from '@org-name/shared/helpers/color';
import {
WidgetInitOptions,
WidgetCommunicationData,
InitProps,
} from '@org-name/shared';
Then I have added the exact locations of where these things can be found to the tsconfig.json
in the app:
"compilerOptions": {
...
"rootDirs": [
"../../libs/shared/src/helpers/color",
"../../libs/shared/src/models"
]
},
Hmm, I feel like this is a recurring issue. There was a long thread where people asked about ability to bundle multiple workspace libs (not event buildable ones) into one package. It was closed with a decision that NX does not support it, and you shouldn't do it. That being said I very much disagree with that decision, and existence of this new issue suggests that I am not alone in that.
I do agree that for 80% of cases making every lib publishable is the way to go. But there is that remaining 20% where that doesn't make sense. Where I work we use monorepo for my team, not entire organisation. We are expected to deliver a package that other team consumes. They only need that one package, yet we end up building 10 of them because of that restrictions. No one cares or needs remaining 9. We use them to structure our code and create boundaries but we are forced to publish them. This also makes the build and publish steps extremely longer, as I am not building and publishing 1 but 10 packages.
I know that NX Cloud could make that a little faster but:
Don't get me wrong, this is a great tool. I use it in my private repository, but to introduce something like that to the work environment is a lot harder. There is pricing, but also security implications, not to be done overnight.
@Bielik20 Maybe you shouldn't break them into 10 libraries. You can have multiple modules in one package. I don't see much benefit to break it up unless it helps speeding up the build process because of the incremental build. But in your case, it doesn't. Maybe you shouldn't break it up. As for NX cloud, I think it makes it much faster. And I think it worth the money to pay NX. We want open source projects can have a way to live and grow.
@maxisam Yeah, that 10 libs and 1 was a simplification, sorry I didn't want to dive too much into details. It is a couple of libs that hold some "shared" functionalities and then couple that "really" get published. Still two libs that "really" get published are never included in the same project, so it would still be ok to bundle all the code inside. Having it split that way allows us to only run tests and publish those that changed using NX affected.
My point is that, there are use cases where you would want to bundle multiple libs together.
Another issue is that the way I publish those libs is suboptimal, but I don't know how to do it in NX, as there is no mechanism to track version of individual libs like lerna does. I think there is somewhere here issue for that as well. So when I detect that lib changed I need to republish all its dependencies with a new version (so no NX cache for me, because I need to bump version) even though they have not changed. Now version is not committed, but kept as a github tag (using semantic release), and I really do not want to commit that version to repo. We are getting off topic, but I am trying to illustrate here is that there are many use cases and sometimes (not most of the time, but still) bundling everything into one lib is actually a way to go.
@Bielik20 Well, like you said you want to avoid unnecessary test and build, so you split it. Therefore, it is unfair to say "This is a paid solution created by nrwl to solve the problem manufactured by nrw". You had a problem already and NX is just trying to fix you problem. :-)
Just a thought, have you thought about using dependency in package.json in the library? https://github.com/ng-packagr/ng-packagr/blob/master/docs/dependencies.md#allowing-in-the-dependencies-section
Btw, why do you need to republish all its dependencies with a new version? for maintenance purpose? I think your second question is more about DevOps.
@maxisam I don't want to spam here, I am happy to discuss details with you though. Since there is no messaging on GitHub, if you want to talk in more details, please create an issue in here ;)
Here I just want to clarify. I think NX is a great tool and I love using it. NX Cloud is also a great idea. What I tried to say was that given NX is essentially a DevOps tool, it lacks in flexibility when it comes down to building publishable libs.
i would love the feature to bundle a library which includes all dependencies and not having to find a "hack" which makes it kinda work. i dont want to publish every dependency in order to use them in the library that i actuall want to publish.
i would love the feature to bundle a library which includes all dependencies and not having to find a "hack" which makes it kinda work. i dont want to publish every dependency in order to use them in the library that i actuall want to publish.
Ya. I have tons of libraries in my workspace and I want to expose only 1 lib which built by combining some other libs and publish it to npm for my customer to download and install. Because I have a security rule that prevents publishing too much source code to npm. And I also don't want to manage the npm version of many libs.
Do we have any solution for this ?
i would love the feature to bundle a library which includes all dependencies and not having to find a "hack" which makes it kinda work. i dont want to publish every dependency in order to use them in the library that i actuall want to publish.
Ya. I have tons of libraries in my workspace and I want to expose only 1 lib which built by combining some other libs and publish it to npm for my customer to download and install. Because I have a security rule that prevents publishing too much source code to npm. And I also don't want to manage the npm version of many libs.
I also need this.
I would also be interested in a solution here. The builders for the apps also bundling the internal lib dependencies. So it should definitely be possible to do this. What would be awesome is to be able to configure which internal dependencies (maybe also external dependencies) to bundle.
@dangviettuan
I cannot make it work for the case when I import only types from another library.
example:
import { InterfaceName } from "@org/library"
it just stays like that. Is it possible to somehow import types from another library?
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! ๐
I noticed it doesn't add the NPM modules used to the package.json
in the dist
build output to publish as I expected. My thought is to just use the command to grab the NX deps and crawl it, then read the rootpackage.json
file and just sync it all up is my thought on how I'd work around this issue unless it's going to be tackled more in the future.
Edit: I checked today and noticed it's working as expected now... Not sure what I could have changed, maybe since I added @nrwl/web
since was getting an error about something missing when doing Jest match inline snapshots? I kinda think it'd be neat to mark if a peerDependencies
but I think for that just create a blank placeholder and write a little post processing script. Then maybe I'll write a custom "build and publish all" script if last and current version doesn't match, but I'm starting to like this setup!
Really useful feature. Struggle myself. +1 please add it to nx
Same problem here we have a list of libs which needs to be published and to deploy them manually is an absolute overkill. Would love to see something from NX here which helps us in this process.
It's been a whole year since this issue was opened, could we at least get a comment from an official NX dev?
Nx dev team Look at this issue, theres alot of people who needs this feature discussed in this issue!
It will be nice to have this feature.
@vsavkin can we please get some attention of NX team please on this issue? It could be a huge thing if we could use NX for developing packages that are split in several libraries and then exported in one npm package
Any update on this issue so far, it seems sharing every internal lib that doesn't need to be known to consumer of package is additional work.
@FrozenPandaz, what do you think about this ask? It be wonderful if we can get this feature.
I'm not sure the OP's use case and what everyone else here is talking about, the same issue as mine, it seems like this is out of the box stuff?
I have a monorepo with one package having a dependency upon both external and internal packages, I need to publish it. When I built it, I get all my deps in the peerDependencies
. I want everything bundled in one js file that I can publish.
Is this the right issue that represents my problem?
I'm not sure the OP's use case and what everyone else here is talking about, the same issue as mine, it seems like this is out of the box stuff?
I have a monorepo with one package having a dependency upon both external and internal packages, I need to publish it. When I built it, I get all my deps in the
peerDependencies
. I want everything bundled in one js file that I can publish.Is this the right issue that represents my problem?
Not really, lets say youre building a react-library. You don't want react to be bundled into your code. That means you have 2 react versions. The user of your package has a react version and your react version. Your package gets unecessary large
We are also running into this issue. The use case we have is that we distribute several packages which have some shared code. That code is extracted into a shared lib, and we want to be able to bundle that code into each published lib rather than maintaining a bunch of separate published libs for each of these shared bits of code. The shared code is not something we want to be public on npm, but Nx forces us to either do this or just copy and paste the code into each of the packages that need it.
To me what we want seems similar in philosophy to how an application
is meant to be written in Nx. If we follow the mental model outlined here:
https://nx.dev/structure/applications-and-libraries#mental-model
but swap "application" for "published package" then it seems to me to be the same thing. In both cases, we want to use Nx to easily reuse code across multiple projects and bundle everything together into one artifact. Using libs to share code is core to how you're supposed to work with Nx, and adding the overheard of requiring that each of those libs be published to npm when they are required by a library (but not when they are required by an application) only adds unnecessary friction to developing the "Nx way".
What we would like is the ability to have "publishable" dependencies of our published packages be treated as such, and built / published separately while being automatically added to the package.json of the parent package (basically the current behaviour). In addition, packages that are not "publishable" should be bundled inside of the outer package instead, and a dependency should not get added to the package.json
+1
We are also running into this issue. The use case we have is that we distribute several packages which have some shared code. That code is extracted into a shared lib, and we want to be able to bundle that code into each published lib rather than maintaining a bunch of separate published libs for each of these shared bits of code. The shared code is not something we want to be public on npm, but Nx forces us to either do this or just copy and paste the code into each of the packages that need it.
To me what we want seems similar in philosophy to how an
application
is meant to be written in Nx. If we follow the mental model outlined here: https://nx.dev/structure/applications-and-libraries#mental-model but swap "application" for "published package" then it seems to me to be the same thing. In both cases, we want to use Nx to easily reuse code across multiple projects and bundle everything together into one artifact. Using libs to share code is core to how you're supposed to work with Nx, and adding the overheard of requiring that each of those libs be published to npm when they are required by a library (but not when they are required by an application) only adds unnecessary friction to developing the "Nx way".What we would like is the ability to have "publishable" dependencies of our published packages be treated as such, and built / published separately while being automatically added to the package.json of the parent package (basically the current behaviour). In addition, packages that are not "publishable" should be bundled inside of the outer package instead, and a dependency should not get added to the package.json
Excellent explanation of the problem and motivation to add this feature @ajwootto ! Hope this issue gets some attention soon.
Hope so too, we are forced to publish libs we don't want to in cases where code duplication would be too extreme. In other cases we actually go the copy & paste route - overall the situation makes me extremely unhappy.
This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! ๐
Not stale!
Currently facing the same issue :/
Same here!
yeeeees
Samer here
yes same problem here too.
Same problem as well :-(
same here
any solution so far?
Still the same issue!
Hi all, Nx 15 will come with an experimental feature that allows @nrwl/js
to achieve this. Keep an eye out for the release blog post and give it a try. This is a tricky feature to get right so we're definitely looking for a lot of feedback.
@nartc NX 15 has been out for a couple of weeks now. Do you know if this experimental feature has already been added?
I got an error while trying to publish my library. Here is example source code: https://github.com/dangviettuan/nx-publishable I have:
Originally posted by @dangviettuan in https://github.com/nrwl/nx/issues/3602#issuecomment-768173108