In a previous blog post, we announced some changes to the way we handle module imports in Polymer 3.0, and described why we made those changes. We're happy to announce that you can try out the new import syntax in the latest Polymer 3.0 preview ( 3.0.0-pre.12 ).

To jump right in, follow the guide in the quick start section, or read on for full details.

Quick start with the latest preview (3.0.0-pre.12)

To get started with the latest Polymer preview:

Update the Polymer CLI tools: npm install -g polymer-cli@next Update the Polymer library and element dependencies in your project to use version 3.0.0-pre.12 . For example, modify package.json : { "name" : "start-polymer3" , "version" : "1.0.0" , "main" : "index.js" , "repository" : "https://github.com/polymerlabs/start-polymer3.git" , "author" : "The Polymer Project Authors" , "license" : "BSD-3-Clause" , "dependencies" : { "@polymer/paper-checkbox" : "^3.0.0-pre.11" , "@polymer/polymer" : "^3.0.0-pre.11" } } { "name" : "start-polymer3" , "version" : "1.0.0" , "main" : "index.js" , "repository" : "https://github.com/polymerlabs/start-polymer3.git" , "author" : "The Polymer Project Authors" , "license" : "BSD-3-Clause" , "dependencies" : { "@polymer/paper-checkbox" : "^3.0.0-pre.12" , "@polymer/polymer" : "^3.0.0-pre.12" } } Update imports that use Element from polymer-element.js . The Element export from polymer-element.js has been renamed to PolymerElement : import { Element as PolymerElement } from './node_modules/@polymer/polymer/polymer-element.js' ; import './node_modules/@polymer/paper-checkbox/paper-checkbox.js' ; import { PolymerElement } from '@polymer/polymer/polymer-element.js' ; import '@polymer/paper-checkbox/paper-checkbox.js' ; If you use the polymer.js module, update import statements to use its new name, polymer-legacy.js : import './node_modules/@polymer/polymer/polymer.js' ; import '@polymer/polymer/polymer-legacy.js' Remove the node_modules folder from your project, then reinstall dependencies: cd your-root-project-folder rm -r node_modules yarn install --flat

Read on for full details on the changes in the new preview.

Changes in 3.0.0-pre.12

Renamed base element export in polymer-element.js (breaking change)

Previously, it was necessary to change the symbol for the main export of @polymer/polymer/polymer-element.js from Element to some other symbol on import. This export has been renamed to PolymerElement . You can now use this symbol without changing it:

import { PolymerElement, html } from '@polymer/polymer/polymer-element.js' ; class MyApp extends PolymerElement { } customElements.define( 'my-app' , MyApp);

Renamed polymer.js to polymer-legacy.js (breaking change)

The collection of imports formerly known as polymer.js has been renamed to polymer-legacy.js .

polymer-legacy.js imports:

The legacy element mixin and related behaviors

The DOM template, array selector and custom style helper elements

The html helper function

Simpler module imports

In this release, we add support for importing npm modules using their package names. From now on, we recommend using package names instead of paths to import npm modules in your Polymer apps and elements.

For example, instead of referring to the Polymer library by its path, as we did in previous Polymer 3.0 releases:

import { Element as PolymerElement } from './node_modules/@polymer/polymer/polymer-element.js' ;

You can now refer to the Polymer library using its package name.

import { PolymerElement } from '@polymer/polymer/polymer-element.js' ;

Using package names in your imports makes it easier to install third-party dependencies, and removes the need to juggle the different path styles of elements and applications. Previously, for example, you had to import the Polymer library from ./node_modules/@polymer/polymer/polymer-element.js in apps, and from ../@polymer/polymer/polymer-element.js in reusable elements. Now, apps and reusable elements can both import from @polymer/polymer/polymer-element.js .

The Polymer CLI tools automatically resolve and rewrite imports that use package names to imports that use paths, producing web-compatible code for the browser.

At present, web browsers need the full path to an import to process it. A discussion on supporting imports by package name in browsers is ongoing-for example, see this proposal for package name maps.

What you need to do

If you're converting a Polymer 2.x project to Polymer 3.0:

You don't need to change your code-the Polymer Modulizer will handle that. We recommend you run the modulizer with the --import-style=name option to generate Polymer 3.0 code that uses package names to import modules.

If you're updating earlier Polymer 3.0 code to use the new preview:

We recommend you change any imports of npm packages to use package names, like in the examples below.

If you're writing Polymer 3.0 code with the new preview:

We recommend you import npm packages using their package names, like in the examples below.

Everyone:

Continue to use paths to import modules that are parts of your app. For example: import './my-view.js' Valid import paths that start with / , ./ , or ../ won't be transformed by the Polymer CLI tools.

When serving code that uses the new Polymer 3.0 preview, run polymer serve with the --npm and --module-resolution=node options. You can set these options from command line flags, or from polymer.json . See the section of this post on Tools for detailed instructions.

Potential questions and answers

Can I still use paths to import my dependencies?

Yes. The Polymer CLI tools won't try to transform import paths that start with / , ./ , or ../ into package names.

What happens if I mix paths and package names?

Your code will work as normal. The Polymer CLI tools won't try to transform import paths that start with / , ./ , or ../ into package names.

Which tools have been updated to handle imports that use package names?

All of the Polymer CLI tools have been updated with this functionality (although polymer build is still a work in progress). Set the --module-resolution=node and --npm options to enable the new functionality.

See the Tools section of this post for more detail.

Use the new import syntax

To import and use the Polymer library:

import { PolymerElement } from '@polymer/polymer/polymer-element.js' ; ... class MyElement extends PolymerElement { ... }

To import and use a helper element from the Polymer library:

import '@polymer/polymer/lib/elements/dom-if.js'; ... class MyElement extends PolymerElement { <template is="dom-if"> ... </template> }

To import a Polymer Element:

import '@polymer/paper-checkbox/paper-checkbox.js' ; ... <paper-checkbox> </ paper-checkbox >

To import a behavior:

import {IronResizableBehavior} from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js' ;

You can also import entire modules in one go, like Polymer.Async :

import * as async from '@polymer/polymer/lib/utils/async.js' async .microTask.run(callback);

The Polymer 3.0 API docs are still in progress-so for the moment, refer to the Polymer 3.0 preview source code to determine what a module exports.

See the MDN documentation on import for more information.

Old Polymer 3.0 preview syntax

import { Element as PolymerElement } from './node_modules/@polymer/polymer/polymer-element.js' ; import './node_modules/@polymer/polymer/lib/elements/dom-if.js' ; import './node_modules/@polymer/paper-checkbox/paper-checkbox.js' ; import './my-view.js' ; class MyApp extends PolymerElement { static get template () { return ` <h1>Hello World</h1> <template is="dom-if" if="true"> <paper-checkbox>I like pie</paper-checkbox> </template> <my-view></my-view> ` ; } } customElements.define( 'my-app' , MyApp);

< script type = "module" src = "./my-app.js" > < my-app > </ my-app >

Current Polymer 3.0 preview syntax

import { PolymerElement, html } from '@polymer/polymer/polymer-element' ; import '@polymer/polymer/lib/elements/dom-if' ; import '@polymer/paper-checkbox/paper-checkbox' ; import './my-view.js' ; class MyApp extends PolymerElement { static get template () { return html` < h1 > Hello World </ h1 > < template is = "dom-if" if = "true" > < paper-checkbox > I like pie </ paper-checkbox > </ template > < my-view > </ my-view > ` ; } } customElements.define( 'my-app' , MyApp);

< script type = "module" src = "./my-app.js" > < my-app > </ my-app >

An update on dynamic imports

The latest versions of Chrome and Safari support dynamic imports using the import() operator (a polyfill is still to come).

The import operator acts like a function, and returns a Promise :

import ( 'my-view1.js' ).then( ( MyView1 ) => { console .log( "MyView1 loaded" ); }).catch( ( reason ) => { console .log( "MyView1 failed to load" , reason); });

Dynamic imports enable lazy-loading of resources, replacing the functionality that we previously used for this in Polymer 2.0 ( Polymer.importHref() ).

The Polymer CLI development server ( polymer serve ) now resolves package names to paths, and rewrites them on-the-fly. Set the --npm and --module-resolution=node options to enable this functionality. You can set these options from command line flags, or from polymer.json .

To set the options from command line flags, for example:

polymer serve --npm --module-resolution=node

To set the options from your polymer.json file, add them as top-level properties. For example:

{ "npm" : true , "moduleResolution" : "node" , }

New polymer.json properties

To support new functionality, we made a few new polymer.json options you should know about. These options are all top-level properties.

root : Optional string. Defaults to the current working folder. The path to the root project folder. This can be an absolute path, or a path relative to the current working folder. "root": "/full/path/to/myfolder" "root": "a/relative/path"

moduleResolution : Optional string. Defaults to "none" . Specifies how the Polymer CLI tools will resolve package names. To disable module specifier rewriting: "moduleResolution": "none" To use Node.js resolution to find modules: "moduleResolution": "node"

componentDir : Optional string. If npm is true , defaults to "node_modules" . Specifies the folder containing this project's components. "componentDir": "path/to/components"

npm : Optional boolean. Sets componentDir to "node_modules" . "npm": true

An update on yarn vs npm and element uniqueness

Because custom elements are registered globally, web components (including the Polymer elements) require uniqueness–that is, you can’t have multiple versions of a single web component in a single project. In older previews of Polymer 3.0, we required users to use yarn and its --flat option to install packages and maintain uniqueness.

This didn't work for many Polymer users. Authors of real-world projects with deep dependency graphs ran into version conflicts for some of their non-web-component dependencies. We're still working out the best way to enforce uniqueness; for example, we'd like package managers to perform deduplication, and custom elements to recognize scope. But as of Polymer 3.0.0-pre.12, a flat installation is no longer required for a Polymer project.

However, custom element uniqueness is still a requirement, and yarn install --flat remains the easiest way to avoid inadvertently importing and registering multiple versions of the same custom element. If your project's dependency graph can be installed this way without any version conflict issues, it's still the best option.

If you can't use --flat , it's no longer a problem: you can choose to use yarn without the --flat option, or to use npm instead. You will, however, need to ensure that your project doesn't try to import different versions of the same custom element.

What next?

With this preview, the core library is feature complete, marking another step on the road to a stable Polymer 3.0 release.

Here's what's still in progress:

The Polymer CLI build tool ( polymer build ).

). Lots of testing.

A complete set of developer and API docs for Polymer 3.0.

The finishing touches (and lots more testing) for the Polymer 3.0 elements. See the elements status page for more info.

JavaScript bundling. Our implementation is based on Rollup.

Lots more testing of the Polymer CLI tools.

Template Polymer 3.0 apps and elements for polymer init .

. Did we mention testing?

See the Polymer 3.0 Roadmap for more info.

Sample app and element with the new preview

We are working on Polymer 3.0 app and element templates that you’ll be able to generate from the Polymer CLI with the polymer init command. In the mean time, take a look at this sample Polymer 3.0 app built with the new preview. A hosted demo is also available.