Replies: 24 comments 23 replies
-
We do support monorepos, and our test suite is actually run on a monorepo! |
Beta Was this translation helpful? Give feedback.
-
Here's a repro: https://github.com/cleric-sh/repro/tree/snowpack-monorepo It's a SPA that references a 'common' package, in a yarn workspaces setup. It builds, but there's no HMR when editing 'common'. |
Beta Was this translation helpful? Give feedback.
-
Here's another repro that uses ts project references. https://github.com/cleric-sh/repro/tree/snowpack-ts-project-references With ts project references, the outDIr and rootDir compilerOptions are used to map the package.json's main field back to the source entry.
|
Beta Was this translation helpful? Give feedback.
-
Ah, yea I see what you mean. Right now we support monorepos (will need to look into https://github.com/cleric-sh/repro/tree/snowpack-ts-project-references to see if it's a bug) but you're right that symlinked packages aren't treated as source files, with full HMR. In Snowpack's model, packages are treated as both "things that don't change often" and "code that must be more processed, since we can't trust that the package author used ESM vs. CJS or an older, non-web native format". This is why we don't support full source-code-like development for symlinked packages by default. But, if there's enough interest, we can look into this more as a feature/enhancement. |
Beta Was this translation helpful? Give feedback.
-
I think the standard approach to determining whether a package should be
HMR'd is to dereference the symlink, and then test whether the path has
'node_modules' in it. If not, then its a workspaces, and should be watched
for changes.
…On Tue, Nov 10, 2020 at 5:22 PM Poorva Gokhale ***@***.***> wrote:
*We will be happy if snowpack incorporates this feature where symlinked
packages are treated as source files, with full HMR.*
We are also having monorepo with 2 packages (we are using yarn workspace
feature). We want changes in one package to be reflected in another packge
like treating it as source files. This is not happening as you pointed out,
symlinked packages aren't treated as source files.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#938 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOXAMRLQRDVCW62YMBJPCDSPFLBXANCNFSM4QMVOZYA>
.
|
Beta Was this translation helpful? Give feedback.
-
We also use a yarn 2 monorepo, and we would like to use snowpack 2 but right now we always need to start dev server with --reload, and in our case its 50+ sec, if any local package is changed (In standard development its change a lot). Its unusable in our case. All of our local package build with rollup to emit esm format. If snowpack can detect that and just use it it will be awesome. In yarn 2 there is no node_modules for dependencies cause its use .pnp.js. So to detect it is a local package:
|
Beta Was this translation helpful? Give feedback.
-
I'm trying out snowpack on an existing lerna/yarn 1 monorepo and I seem to be missing something pretty basic. The app I try to start is a pretty generic react typescript app in a directory To fix this, I can put an alias |
Beta Was this translation helpful? Give feedback.
-
import { aliascalculation } from './babel';
/**
* 插件的导入方法
*
* @export
* @param {*} _snowpackConfig
* @param {*} pluginOptions
* @return {*}
*/
export default function importalias(_snowpackConfig: any, pluginOptions: any) {
return {
name: '@byted/snowpack-import-alias-plugin',
async transform({
id,
contents,
fileExt,
}: {
id: string;
contents: string;
fileExt: string;
}) {
if (fileExt === '.js') {
const result = aliascalculation(contents, id, pluginOptions?.config);
return result;
}
return;
},
};
} /* eslint-disable no-undef */
import generate from '@babel/generator';
import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
interface IPackageConfig {
/**
* 命中包名称
*
* @type {string}
* @memberof IPackageConfig
*/
source_name: string;
/**
* 可替换包名称
*
* @type {string}
* @memberof IPackageConfig
*/
replace?: string;
}
/**
* 转化源码
*
* @param {string} source 源码字符串
* @param {string} id 文件位置
* @param {IPackageConfig[]} config 基本配置
* @return {*}
*/
function aliascalculation(
source: string,
id: string,
config: IPackageConfig[],
) {
const ast = convertast(source);
handle(ast, config);
const new_code = generate(ast, {}, { [`${id}`]: source })?.code;
return new_code;
}
function convertast(origin_code: string) {
/** 解析源码AST树 */
const ast = parse(origin_code, {
sourceType: 'module',
plugins: [
'typescript',
'jsx',
'decorators-legacy',
'classProperties',
'bigInt',
'importMeta',
'optionalChaining',
'nullishCoalescingOperator',
'importMeta',
'optionalCatchBinding',
],
});
return ast;
}
function handle(ast: babel.types.File, config: IPackageConfig[]): void {
const matchsource = (source: string) => {
return config.filter(p => p.source_name === source).length > 0;
};
traverse(ast, {
enter(path) {
if (path.isImportDeclaration() && matchsource(path.node.source.value)) {
const item = config.find(x => x.source_name === path.node.source.value);
if (item?.replace) {
path.node.source.value = item.replace;
}
} else if (
path.isCallExpression() &&
path.node.callee.type === 'Import' &&
matchsource((path.node.arguments?.[0] as any).value ?? '')
) {
const item = config.find(
x => x.source_name === (path.node.arguments?.[0] as any).value ?? '',
);
if (item?.replace) {
(path.node.arguments?.[0] as any).value = item.replace;
}
}
return;
},
});
}
export { convertast, handle, IPackageConfig, aliascalculation };
|
Beta Was this translation helpful? Give feedback.
-
const fs = require('fs');
const path = require('path');
const cwd = process.cwd();
const isTS = fs.existsSync(path.join(cwd, 'tsconfig.json'));
module.exports = {
mount: {
public: '/',
src: '/src',
'../swagger-analysis': '/swagger-analysis',
'../aux-utility': '/aux-utility',
},
plugins: [
'@snowpack/plugin-dotenv',
[
'snowpack-import-alias-plugin',
{
config: [
{
source_name: 'aux-utility',
replace: '/aux-utility/es/aux-utility.js',
},
{
source_name: 'swagger-analysis',
replace: '/swagger-analysis/lib/swagger-analysis.js',
},
],
},
],
],
devOptions: {
port: 4000,
open: 'none',
},
buildOptions: {
sourceMaps: true,
},
installOptions: {
installTypes: isTS,
treeshake: true,
externalPackage: ['aux-utility', 'swagger-analysis'],
},
};
|
Beta Was this translation helpful? Give feedback.
-
What is the status of this issue? I operate in a monorepo, and use typescript references to juggle compilation targets. Snowpack doesn't track them as source files. |
Beta Was this translation helpful? Give feedback.
-
Hey, just came here with the same issue? Any news on how to track monorepo siblings as source code? |
Beta Was this translation helpful? Give feedback.
-
Intuitively, it's probably walking the typescript references and treating
them as source code instead of a module in node_modules.
IIRC, the default behavior for node_module resolution is to dereference
symlinks, and then check the path to see if it belongs to a 'node_modules'
folder.
If the path doesn't contain 'node_modules', then compiler treats the code
as source, and proceeds to compile it.
So in this way, for a monorepo that uses symlinks to treat projects as
node_modules, such as yarn workspaces, typescript will happily compile the
package and all related packages, because it treats them as a single
package.
The downside to this is that shared packages are re-compiled for each
package that references them, and included in their output.
This is different for project references, where tsc will walk the
dependency hierarchy and any shared packages are compiled into their own
dist folder once and only once. The output source is then treated as a
stand-alone node_module by the projects/packages that depend on it.
Overall, it would be worth getting project references fully supported in
this capacity.
…On Thu, Feb 4, 2021 at 12:06 PM Anton Bessonov ***@***.***> wrote:
You're welcome!
I believe this works because of snowpack aliases treating the other
packages as one src input. We're effectively running the snowpack
typescript plugin for ever typescript package. The output from this is then
piped to a single STDOUT.
I can't deduce this behavior. Snowpack started for app package only. In
ts-plugin I don't see any special treating for aliases, just one
subprocess. Even the output of tsc suggest, that there is only one compiler
and I don't see any duplicated messages. Or do you mean that snowpack
creates a "virtual view" of directory structure? Any pointer on why/how
snowpack/tsc works even without project references @FredKSchott
<https://github.com/FredKSchott> ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#938 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOXAMQ2WADT5XTL2F5RVWTS5JWQTANCNFSM4QMVOZYA>
.
|
Beta Was this translation helpful? Give feedback.
-
Totally possible... my experience is merely anecdotal from trying to get
fuse-box to play nice with ts project references :)
I believe @ahnpnl <https://github.com/ahnpnl> also has some experiences
trying to get ts-jest working with ts project references that might be
helpful!
…On Thu, Feb 4, 2021 at 2:02 PM Edward Mulraney ***@***.***> wrote:
The downside to this is that shared packages are re-compiled for each
package that references them, and included in their output.
I haven't confirmed it, but I don't think they'll be recompiled. tsc is
running only once (via the snowpack typescript plugin) and is effectively
running over your monorepo packages as a single codebase. It has no idea
it's a monorepo or that the other packages aren't just a relative path with
more source code. My guess would be that alias and mount in
snowpack.config.js take precedence over checking node_modules. Perhaps
@FredKSchott <https://github.com/FredKSchott> can confirm?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#938 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOXAMWAH2DG6OKDLOEPTODS5KEGVANCNFSM4QMVOZYA>
.
|
Beta Was this translation helpful? Give feedback.
-
This seems a pretty big deal as it affectively means those using TS cant use snowpack easily in a lerna or yarn workspace. Snowpack 3 very much does not work out of the box for multi-module projects. Ive tried to understand all of the above but I'm struggling to read between the lines to see what the current workaround is, if there is one? Do I need to:
|
Beta Was this translation helpful? Give feedback.
-
Hey everyone, really appreciate your patience on this one (and thanks @adam-thomas-privitar for the ping). Snowpack was built on a pretty solid understanding that packages = static & built only once, which made monorepo support especially difficult to add on later. I just completed a big rewrite/cleanup of the Snowpack internals to specifically address this, which is now available at: #2707. Monorepo/workspace npm packages are now treated as source code by default, which means they get instant rebuilds on file change.
I'd love any help testing this, if you can check out this new version and run it in your project. If you run into any issues, please post in that PR. This doesn't address the tsconfig automatic mapping brought up in the OP, but once this PR is settled and out I would be +1 for a PR to snowpack to automatically read aliases from tsconfig.json "paths". |
Beta Was this translation helpful? Give feedback.
-
@FredKSchott Thank you for the update! Can you please drop a line on how it works currently? I'm asking because it seems like it works already. From this comment:
|
Beta Was this translation helpful? Give feedback.
-
I now had the time to test again and I came much further, the monorepo problem probably is fixed.
The file Should I open a new issue for this or is there an easy fix? |
Beta Was this translation helpful? Give feedback.
-
Is there a canonical example repository that is failing? |
Beta Was this translation helpful? Give feedback.
-
FYI, I did a new repo with snowpack and a UI Library built with Typescript in a monorepo: https://github.com/horacioh/snowpack-and-ui-lib-demo maybe this can help to others too! |
Beta Was this translation helpful? Give feedback.
-
Snowpack seems to work with sibling packages now, but it doesn't seem to run |
Beta Was this translation helpful? Give feedback.
-
it doesn't seem to run esinstall on sibling package node_modules
I am experiencing this also.
… On May 19, 2021, at 9:40 AM, Utsav Shah ***@***.***> wrote:
Snowpack seems to work with sibling packages now, but it doesn't seem to run esinstall on sibling package node_modules. Is this likely a misconfiguration on my end, or is that expected?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub <#938 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABNSMS3C6IX7GFWOZNFMJOLTOPSY5ANCNFSM4QMVOZYA>.
|
Beta Was this translation helpful? Give feedback.
-
I'm having similar issues, I've got a project structured similarish to monorepos and lerna (although using git submodules, but that's not actually the cause of the issue). Basically I am wanting to keep my general library codes separate from repositories that use them as I share a number of libraries between components/projects a lot, as such I've been trying to move to a structure that uses local Now I've been trying to use some of this as a part of a Snowpack project but have been getting issues with the fact that Snowpack tries to resolve any I've made a sample repo to demonstrate what I mean: https://github.com/Jamesernator/snowpack-issue In the repo I have a What I expected to happen was, due to having a TS project reference, that Snowpack would compile the package prior to performing this resolution. Although alternatively it could equally well check on a failed lookup to see if there's a corresponding source file (which fits more in line with the single-file compilation). My ideal behaviour would be that Snowpack compiles the e.g. If we were outputting an import map (without bundling), this is the sort've I'd expect from the sample repo: {
"imports": {
"example-element/": "./packages/example-element/"
},
"scopes": {
"./packages/example-element": {
"rxjs": "../path/to/.snowpack/rxjs.bundle.js",
"example-library/": "./packages/example-element/packages/example-library/"
}
}
} As mentioned by others, it shouldn't be particularly difficult to distinguish source packages from external, just check if the depdendency is |
Beta Was this translation helpful? Give feedback.
-
Something I haven't seen mentioned in this thread; I believe the primary benefits of typescript project references are 1. incremental builds for sibling dependencies; 2. language server "go to definition" links to the source file instead of the type definitions; and 3. languge server type checking on unsaved files in sibling dependencies. Number 2 is a constant gumption trap in my dayjob and I hate it. There are plenty of ways to do a build watch in a monorepo, but without native project reference support you don't get go to definition. |
Beta Was this translation helpful? Give feedback.
-
After reading this thread I am still confused. Here is the use case I have: Folder structure
Each folder is it's own package but all import from I've managed to get everything but "admin-ui", which is the one that uses Snowpack, working with the appropriate aliases to import from |
Beta Was this translation helpful? Give feedback.
-
Last I checked, snowpack broke badly in a monorepo environment. I have a monorepo with yarn workspaces linked by typescript project references.
Ideally, snowpack would be able to detect node_modules that are yarn workspaces (you can dereference the symlink and check whether the path contains node_modules) and build & serve them as web modules. And watch them too.
Likewise with typescript project references.
Snowpack actually has an edge in this regard because there's no bundling, the whole process could (potentially) be so much simpler... e.g. walk dependencies and run esbuild on each one.
It would be so refreshing to have a fast dev environment that just 'works' with monorepo features.
Beta Was this translation helpful? Give feedback.
All reactions