Description
Actual
When svelte-loader
is symlinked for dev (using npm link
or npm install /path/to/local/svelte-loader
) then it always requires its own bundled version of svelte
(which is only included to run svelte-loader
's tests).
Expected
The expected behaviour is to always require the svelte
version that is in the app's node_modules
, except when running svelte-loader
's own tests.
Why it happens?
Node resolves modules from their canonical directory, not symbolic ones.
Line 7 in 6f650f1
NOTE
Last versions of template-webpack
have an resolve.alias
in webpack config that is intended to fix a similar issue. However, in this case, svelte
is resolved by node, not webpack, so this fix does not apply.
Why it should be fixed?
This bug can only affect people who are cloning svelte-loader
for any reason but, when it bites, it is very unobvious what's happening. This is especially true when the 2 conflicting versions of svelte
are close, or (the worse) if the developer is also working on something in svelte
and has linked its local svelte
in its test app (and they'll have to understand why their changes are ignored).
So this bug will harm contribution to svelte-loader
, and discourage people wanting to experiment with it.
Also, this is not demonstrated in this issue, but this bug can be a blocker to setting up tooling around svelte-loader
(e.g. a test suite) that lives in another package.
Reproduction
NOTE This example uses Svelte 2 because it makes the behaviour easier to demonstrate, but the problem is the same with last versions of svelte
/ svelte-loader
/ template-webpack
.
Let's say I have a Svelte 2 app:
git clone git@github.com:sveltejs/template-webpack.git
cd template-webpack
git checkout 5cdbfcc4011acdf11e8a7da06d8309102b827d5c
# with latest svelte-loader
npm i svelte-loader@latest
npm ls | grep svelte
> svelte-app@1.0.0
> ├── svelte@2.16.1
> ├─┬ svelte-loader@2.13.6
> │ └── svelte-dev-helper@1.1.9
npm run dev
✔️ It works.
Now let's grab a local copy of svelte-loader:
cd ..
git clone git@github.com:sveltejs/svelte-loader.git
cd svelte-loader
npm install
npm ls | grep svelte
> svelte-loader@2.13.6
> ├── UNMET PEER DEPENDENCY svelte@3.0.0-beta.5 # ???
> └── svelte-dev-helper@1.1.9
> npm ERR! peer dep missing: svelte@>1.44.0, required by svelte-loader@2.13.6
cat package.json | grep -E 'Dep|"svelte":'
> "devDependencies": {
> "svelte": "^3.0.0-beta.5"
> "peerDependencies": {
> "svelte": ">1.44.0"
# => npm gets a bit confused between peer / dev dependencies, apparently...
npm test
> ...
> 20 passing (83ms)
✔️ all tests passing on our local svelte-loader
Now, let's try our local svelte-loader in our Svelte 2 app:
cd ../template-webpack
npm install ../svelte-loader
npm run dev
> ERROR in ./src/App.html
> Module build failed (from ../svelte-loader/index.js):
> ...
> ℹ 「wdm」: Failed to compile.
❌ broken
Let's fix it:
mv ../svelte-loader .
rm -r node_modules
npm install svelte-loader
ls -l node_modules | grep svelte-loader
> svelte-loader -> ../svelte-loader
npm ls | grep svelte
> svelte-app@1.0.0
> ├── svelte@2.16.1
> ├─┬ svelte-loader@2.13.6 -> /tmp/svelte-loader.symlink/template-webpack/svelte-loader
> │ ├── svelte@3.0.0-beta.5 extraneous
> │ └── svelte-dev-helper@1.1.9
npm run dev
> ...
> ℹ 「wdm」: Failed to compile.
❌ still broken
Now, let's force svelte-loader to use the same svelte as the app:
rm -r svelte-loader/node_modules/svelte
npm ls | grep svelte
> svelte-app@1.0.0
> ├── svelte@2.16.1
> ├─┬ svelte-loader@2.13.6 -> /tmp/svelte-loader.symlink/template-webpack/svelte-loader
> │ ├── UNMET DEPENDENCY svelte@3.0.0-beta.5
> │ └── svelte-dev-helper@1.1.9
npm run dev
> ...
> ℹ 「wdm」: Compiled successfully.
✔️ Now it works again.