Polymer: Encourage proper relative imports of polymer in elements

Created on 22 Oct 2018  路  5Comments  路  Source: Polymer/polymer

Most elements in PolymerElements repo incorrectly import polymer via @polymer like so:

import '@polymer/paper-styles/typography.js';

Chrome does not recognize such imports and throws Failed to resolve module specifier. Relative references must start with either "/", "./", or "../".

Unfortunately this introduces a required step of having to build or serve via polymer-cli, which is not always an option (https://www.polymer-project.org/blog/2018-05-25-polymer-elements-3-faq).

If elements use proper relative imports: import '../paper-styles/typography.js'; or import '/node_modules/@polymer/paper-styles/typography.js'; we could run an app without having to build every single time we make a change.

Also an app may need to be hosted in IIS Express or another dev environment that provides some server-side functionality - so polymer serve may not be an option either.

Unless there's a way to have the browser do node module resolution I think we should be using standard syntax that works more broadly.

Thank you

Most helpful comment

However you do it, you will always need to path transformation.

import '/node_modules/@polymer/paper-styles/typography.js' would not work because you force all consumers to have node_modules in the root of their domain. This can be an issue when hosting.

import './node_modules/@polymer/paper-styles/typography.js' would work in the element's repository, but not once the element is installed as it tries to resolve to the node_modules folder inside the element's package. (node_modules/@polymer/paper-styles/node_modules).

import '../@polymer/paper-styles/typography.js' would would when installed, but it would not work inside the element's repository as it tries to reach outside the element's directory.

The last approach is what was done with bower, but it required a path transformation step when running element projects.

The bare import specifier is the de facto standard right now in JS land, in almost all cases you anyway need to do some kind of build time processing of your code. Even if you don't transpile or bundle, you want to minify your code. Resolving the imports is then a small step, for great develop experience and source code maintenance. You are not limited to the polymer cli, because it's a standard practice all other build tools do this as well. For example you can check out webpack and rollup.

There is also work being done to make browsers work with the bare import specifiers through package name maps.

All 5 comments

You can read more about the reasons behind this change here:
https://www.polymer-project.org/blog/2018-02-26-3.0-preview-paths-and-names

There is a "proof of concept" of a simple transform tool eliminating the need for build process:
https://github.com/PolymerLabs/empathy/tree/initial-implementation

Thanks for pointing out empathy - it could be an acceptable workaround.

It spits out some errors though:

Could not resolve module specifier "@polymer/iron-validator-behavior/iron-validator-behavior.js"
Could not resolve module specifier "@polymer/iron-icons/iron-icons.js"
Failed to mark bare specifier for @polymer\app-layout\templates\getting-started\x-app.js
Failed to mark bare specifier for @polymer\app-layout\templates\shrinesrc\shrine-simple-item.js
...

If empathy is one of your recommendations to solve the incorrect imports problem could you make it official and add to the FAQ?

However you do it, you will always need to path transformation.

import '/node_modules/@polymer/paper-styles/typography.js' would not work because you force all consumers to have node_modules in the root of their domain. This can be an issue when hosting.

import './node_modules/@polymer/paper-styles/typography.js' would work in the element's repository, but not once the element is installed as it tries to resolve to the node_modules folder inside the element's package. (node_modules/@polymer/paper-styles/node_modules).

import '../@polymer/paper-styles/typography.js' would would when installed, but it would not work inside the element's repository as it tries to reach outside the element's directory.

The last approach is what was done with bower, but it required a path transformation step when running element projects.

The bare import specifier is the de facto standard right now in JS land, in almost all cases you anyway need to do some kind of build time processing of your code. Even if you don't transpile or bundle, you want to minify your code. Resolving the imports is then a small step, for great develop experience and source code maintenance. You are not limited to the polymer cli, because it's a standard practice all other build tools do this as well. For example you can check out webpack and rollup.

There is also work being done to make browsers work with the bare import specifiers through package name maps.

@LarsDenBakker I'm looking to do the path transformation once (when I update the node_modules repository) and empathy seems like a possible solution for that.

I use polymer build in the end to generate deployable bundles of the app.

Closing as duplicate of https://github.com/Polymer/polymer/issues/5238#issuecomment-390012108 and https://github.com/Polymer/polymer/issues/5431#issuecomment-437599257. Please see those threads/comments and a blog post on the topic for more details on the reasoning that went into the decision-making for package names being the only non-standard convention used in published Polymer Project source.

@pika/web is also an exciting new tool worth following in this space.

Was this page helpful?
0 / 5 - 0 ratings