Search code examples
webpackbowerpolymer-2.xwebpack-4

Can't resolve dependencies with webpack 4 and bower


I am trying to bundle my application with webpack 4, it's a application based in Polymer, with dependencies in bower, and HTML files

This is my webpack config:

'use strict';

const webpack = require('webpack');

/* global __dirname module require */
/* eslint comma-dangle: ["error", "never"] */
const path = require('path');

module.exports = {
    entry: './my-entry.html',
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, './dist'),
        publicPath: 'dist/'
    },
    resolve: {
        modules: ['bower_components', 'node_modules'],
        descriptionFiles: ['package.json', 'bower.json']
    },
    devtool: 'inline-source-map',
    module: {
        rules: [
            {
                test: /\.html$/,
                use: [
                    { loader: 'babel-loader' },
                    { loader: 'polymer-webpack-loader' }
                ]
            },
            {
                test: /\.js$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['env']
                        }
                    }
                ]
            }
        ]
    }
};

And when I run webpack, I have the following error:

ERROR in ./my-page.html
Module not found: Error: Can't resolve '../util-custom-types/imports/currency.html' in 'C:\Workspaces\my-project'
resolve '../one-package/imports/currency.html' in 'C:\Workspaces\my-project'
  using description file: C:\Workspaces\my-project\package.json (relative path: .)

this import ../util-custom-types/imports/currency.html is located inside bower_components/util-custom-types/imports/currency.html, and when I run polymer serve without bundling, it works.

Looks like webpack is missing something inside

resolve: { modules: ['bower_components', 'node_modules'],

because it doesn't looks for the file inside those folders.

this is one of the failing imports

<link rel="import" href="../util-custom-types/imports/currency.html">

I have tried some plugins on the internet, but as webpack 4 is pretty new, a lot of them are not working.

I know that if I use the import links pointing to the bower_components folder, like this, <link rel="import" href=".bower_components/util-custom-types/imports/currency.html"> it will work, but it's not a valid solution, as some of the components also have the same way of importing, and I can't modify that.

So, In conclusion, I want to use html imports, pointing to a bower_components folder, like this:

<link rel="import" href="../util-custom-types/imports/currency.html">

to a file located in

./bower_components/util-custom-types/imports/currency.html

in webpack 4, without referencing to the bower_components foder.

Has anyone achieved this?

EDIT:

I have created a sample github project, with just a component creaated from polymer init, and a webpack configuration.

https://github.com/vlaraort/demo_polymer_webpack

It's important to be a component, no a application, because the html imports of polymer are not pointing to bower components, and in a application, the html imports of polymer, points to bower_components.

Component:

<link rel="import" href="../polymer/polymer-element.html">

Application:

<link rel="import" href="../bower_components/polymer/polymer-element.html">

To install, npm i & bower i

To run working polymer serve npm run polymer:dev To run not-working webpack serve npm run webpack:dev

As you can see with the webpack:dev, the polymer element import is trying to fetch from http://localhost:8080/polymer/polymer-element.html, instead of http://localhost:8080/bower_components/polymer/polymer-element.html, and it's failing because that.

So, the objective of the question is to understand what magic is polymer serve doing with the imports, as it resolves this link

<link rel="import" href="../polymer/polymer-element.html">

into bower_components, and how to reproduce that behaviour in webpack.

Thanks!


Solution

  • The relative imports should work fine. You just need to tell webpack to resolve html files.
    Add html to the list of extension.

    resolve: {
        modules: ['bower_components', 'node_modules'],
        descriptionFiles: ['package.json', 'bower.json'],
        extensions: ['.js', '.json', '.html']
    },
    

    EDIT:

    The sample project helped to understand what is wrong here.
    The error has actually nothing to do with webpack. webpack never touches the files in demo. webpack-dev-server only loads index.html in the root directory, which redirects into demo. But nothing gets complied. This is the same as if you would run any other webserver in this directory.
    You can see that by running just webpack without the dev server. It just compiles the index.html.

    Let me try to explain what you want to do instead.
    First, you need to load your root index.html file with something like html-webpack-plugin. This file should not get bundled, or we can't load anything.

    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './index.html'),
      inject: false
    }),
    

    In this file you need to now load everything else. Plus do some polymer magic. The demo application of the polymer-webpack-loader explains this.

    And last, define your webpack entry points. These are now your components. Everything that gets loaded from inside of them with relative paths, including things from bower_components, should just work. Webpack will resolve them and bundle everything up.

    The demo application from the loader is a big help, look at their implementation.
    Sorry the solution isn't as simple as I first though. I hope this helps.