Working on a project where I’m consuming an Aurelia plugin. Everything works great if it’s installed from npm, but trying to get it working with npm link isn’t working right. Has anyone done this before?
Webpack throws an error: https://pastebin.com/c5a1Mmw6
1 Like
Show me your source code around PLATFORM.moduleName('./v-td-image.css')
.
1 Like
Perhaps you’re missing this bit of webpack configuration?
symlinks
webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
1 Like
@huochunpeng just doing this in the View:
<require from="./v-td-image.css"></require>
@mcorven When I set that to false, I get a runtime error: https://pastebin.com/raw/U66PkTV8
1 Like
You have to tell more on how you consume the plugin. I assume <require from="./v-td-image.css"></require>
is a line in your plugin repo, not app repo.
One thing you can try is to use alias in webpack.config.js.
resolve: {
alias: {
'your-plugin-name': path.resolve(__dirname, '../local-plugin-repo/')
}
}
1 Like
Just consuming it like a regular plugin. Installing it from npm, adding it as a global resource, and importing in functions as needed.
Yes, I’m importing that css file inside the plugin. I probably have a couple hundred css files imported that way.
1 Like
I am confused, your description does not tell me what’s the difference from “Everything works great if it’s installed from npm”.
1 Like
If I install it from npm (either from the git repo or with npm pack), webpack builds fine and I can consume the plugin perfectly fine.
If I try to use npm link then the webpack build fails.
1 Like
Sounds like something can be improved. I will get back to you.
At mean time, if you use cli-bundler on new app, it should work with npm linked local plugin.
Update: I confirmed cli-bundler app works with npm link.
1 Like
Update: our webpack-plugin made an assumption that all npm package root folder is behind node_modules (either local, deep local, or upper folder hoisting like lerna workspace). But linked npm package doesn’t have node_modules in their real path (behind the symlink node_modules/linked-plugin/
).
I am not familiar with webpack architecture to fix this issue. I don’t even know whether it’s possible. cc @jods4
function makeModuleRelative(roots: string[], resource: string) {
for (let root of roots) {
let relative = path.relative(root, resource);
if (!relative.startsWith("..")) return relative;
}
return null;
}
function fixNodeModule(module: Webpack.Module, allModules: Webpack.Module[]) {
if (!/\bnode_modules\b/i.test(module.resource)) return null;
// The problem with node_modules is that often the root of the module is not /node_modules/my-lib
// Webpack is going to look for `main` in `project.json` to find where the main file actually is.
// And this can of course be configured differently with `resolve.alias`, `resolve.mainFields` & co.
// Our best hope is that the file was not required as a relative path, then we can just preserve that.
// We just need to be careful with loaders (e.g. async!)
let request = removeLoaders(module.rawRequest)!; // we assume that Aurelia dependencies always have a rawRequest
if (!request.startsWith(".")) return request;
// Otherwise we need to build the relative path from the module root, which as explained above is hard to find.
if (!request.startsWith(".")) return request;
// Otherwise we need to build the relative path from the module root, which as explained above is hard to find.
// Ideally we could use webpack resolvers, but they are currently async-only, which can't be used in before-modules-id
// See https://github.com/webpack/webpack/issues/1634
// Instead, we'll look for the root library module, because it should have been requested somehow and work from there.
// Note that the negative lookahead (?!.*node_modules) ensures that we only match the last node_modules/ folder in the path,
// in case the package was located in a sub-node_modules (which can occur in special circumstances).
// We also need to take care of scoped modules. If the name starts with @ we must keep two parts,
// so @corp/bar is the proper module name.
let name = /\bnode_modules[\\/](?!.*\bnode_modules\b)((?:@[^\\/]+[\\/])?[^\\/]+)/i.exec(module.resource)![1];
name = name.replace("\\", "/"); // normalize \ to / for scoped modules
let entry = allModules.find(m => removeLoaders(m.rawRequest) === name);
if (entry)
return name + "/" + path.relative(path.dirname(entry.resource), module.resource);
// We could not find the raw module. Let's try to find another a more complex entry point.
for (let m of allModules) {
let req = removeLoaders(m.rawRequest);
if (!req || !req.startsWith(name) || !m.resource) continue;
let i = m.resource.replace(/\\/g, "/").lastIndexOf(req.substr(name.length));
if (i < 0) continue;
1 Like
How do I use cli-bundler?
1 Like
When do au new, select last option “custom”, then select cli bundler.
1 Like
Also when adding plugin (helloworld by au-cli) using yarn add …/…/helloworld, webpack bundled (au-cli default) can’t consume plugin. au build seems to build & bundle fine, but when checking bundles {consumingapp}/nodemodules/helloworld/node_modules folder get’s appended . If I delete {consumingapp}/nodemodules/helloworld/node_modules folder, then bundling goes fine and plugin is usable. Any idea how to make local plugin development work with yarn and webpack consuming app? After all, these are generated using au-cli defaults.
1 Like
@avaisane try to change your webpack config from
resolve: {
modules: [srcDir, 'node_modules'],
To
resolve: {
modules: [srcDir, path.resolve(__dirname, 'node_modules')],
This enforces webpack to only use top level npm packages, not those deep ones.
2 Likes
That indeed worked like a charm. Thanks!
1 Like
m0ngr31
October 31, 2019, 3:57pm
17
Making my resolve look like this solved the issue for me:
resolve: {
...
modules: [srcDir, path.resolve(__dirname, 'node_modules')],
symlinks: false,
},
1 Like