All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
- Avoid triggering (ember.js#19392)[emberjs/ember.js#19392] when we produce synthetic class
AttrNode
s.
This major release of Ember CSS Modules primarily removes support for deprecated patterns and updates our minimum support for other elements of the ecosystem.
Ember CSS Modules is now tested against the following as minimum supported versions:
- Ember 3.24
- Ember CLI 3.24
- Node 12
Older Ember and Node versions may incidentally work, but are no longer officially supported.
While ECM will still work for templates backed by Ember.Component
classes, all special handling for such components' implicit root element has been removed, in line with the broader ecosystem shift to template-only and @glimmer/component
components. This includes the following removals:
- the
@localClassNames
and@localClassName
decorators - support for
localClassNames
andlocalClassNameBindings
properties - the
patchClassicComponent
configuration flag
Special support for Ember.Component
was deprecated in v1.5.0 of ember-css-modules
; see the changelog for that release for further advice on migrating to newer Octane-based component APIs.
- You can now pass
patchClassicComponent: false
in your ECM config to opt out of the deprecated monkeypatching ofEmber.Component
that will be removed entirely in 2.0 (thanks @SergeAstapov!)
- Modules whose path includes the name of the package they're in no longer cause issues when resolving
@value
andcomposes:
directives (thanks @eshirley and @maxfierke!)
- ECM's support for binding local class names on the root element of a classic
Ember.Compnent
(thelocalClassNames
andlocalClassNameBindings
properties and the@localClassName
and@localClassNames
decorators) has been deprecated and will be removed in the next major release. These APIs rely on reopeningEmber.Component
(which is itself now deprecated) and can be replaced by several alternative patterns. See the Upgrade Notes section below for migration suggestions.
For classic @ember/component
subclasses, ember-css-modules
has had support for binding static and dynamic local class names to the component's root element using either .extend()
or decorator syntax:
export default Component.extend({
localClassNames: ['always-present'],
localClassNameBindings: ['flipACoin'],
flipACoin: computed(function() {
return Math.random() > 0.5 ? 'yes-class' : 'no-class';
}),
});
@localClassNames('always-present')
export default class MyComponent extends Component {
@localClassName flipACoin = Math.random() > 0.5 ? 'yes-class' : 'no-class';
}
Both versions of these APIs are now deprecated, as:
- they rely on monkey-patching
Ember.Component
, which is itself now deprecated - they're parallels of the
classNames
andclassNameBindings
APIs that are no longer relevant in modern Ember applications
Depending on your appetite for refactoring and modernizing, you might take one of three approaches to migrating off of these APIs:
- Convert your components to use the modern
@glimmer/component
base class instead of@ember/component
. Since Glimmer component templates have "outer HTML" semantics, there's no implicit root element for these APIs to apply to. See the Octane vs Classic cheat sheet for further details on the differences between classic and Glimmer components. - Use
tagName: ''
to remove the implicit root element from your classic component, then add a corresponding explicit root element to your template, where you can uselocal-class
as you would for any other element. - Import the class name mapping from your styles module and use that with the classic
classNames
andclassNameBindings
APIs:import styles from './styles'; export default Component.extend({ classNames: [styles['always-present']], classNameBindings: ['flipACoin'], flipACoin: computed(function() { return Math.random() > 0.5 ? styles['yes-class'] : styles['no-class']; }), });
- We now support a wider range of dependencies that includes PostCSS 8 out of the box. Depending on your package manager, you'll likely see this upgrade take effect automatically when you update ECM, and you may see deprecation warnings for any older PostCSS plugins you're using.
If you're using older PostCSS plugins or an older Node version and wish to continue using PostCSS 7, the appropriate dependency versions are still in range for ECM, and we still run tests against them. The easiest way to lock to those versions locally is likely with resolutions
entries, which you can see an example of in test-package/old-app
.
"resolutions": {
"ember-css-modules/broccoli-css-modules": "^0.7.0",
"ember-css-modules/broccoli-postcss": "^4.0.3",
"ember-css-modules/postcss": "^7.0.35"
},
- Ensure styles from addons that define a custom
moduleName
use correct import paths (#220; thank you @timlindvall!)
- Ensure addons use the host app's
generateScopedName
for consistency if they don't have their own configured.
- Ensure
ember-css-modules
is initialized beforeember-cli-htmlbars
. This almost always was coincidentally the case already, but ordering constraints from other addons could cause ECM to init later, causinglocal-class
in colocated templates not to be processed, as in ember-concurrency-async#4
- Ensure local imports work with CLI 3.12 #197
This is a stable release of the changes included in 1.3.0-beta.1 and -beta.2. Headline additions include support for building in projects using @embroider/concat
and for defining styles when writing components in the component/template colocation layout.
- Support for Embroider's
staticHelpers
flag. #188
- Timing changes to when ECM calculates its configuration caused some addons that late-defined their options (e.g. in their
included()
hook) not to be picked up correctly. This timing has been reverted to match that of ECM stable. #186 - ECM no longer emits a nonsense error message without actionable information when a bad import path is specified for a
@value
orcomposes
directive. #186
- Experimental support for apps built using
@embroider/compat
. Note that, until embroider-build/embroider#309 is fixed, CSS changes will likely not show up on rebuilds (though corresponding JS changes will) - Experimental support for components in the Octane "colocation" layout (see the README for details.)
- A new
includeExtensionInModulePath
option that, when set totrue
, will include.css
(or whatever your configured extension is) in the import path for your modules. Note that the extension is always included in the module name for colocated styles in order not to conflict with the component definition itself.
- Support new template factory format coming in Ember 3.13 #146
- ember-css-modules now works in projects using either stage 1 or stage 2 of the decorators proposal, regardless of whether you're using
@ember-decorators/*
,ember-decorators-polyfill
, or built-in decorator support viaember-cli-babel
>= 7.7 and Ember 3.10.
- ECM's template AST transform no longer prevents ember-cli-babel from performing parallel transpilation.
- ember-css-modules now officially supports being installed in projects running either the 3.x or 5.x series of ember-decorators releases #134
@localClassNames
and@localClassName
now support projects using either stage 1 or stage 2 of the decorators proposal.
- Resolving
@value
s and class names from addons no longer fails for addons that aren't dependencies of the root application. #125 - Projects using ember-css-modules with other preprocessors (like ember-cli-sass) should no longer see those preprocessors fully rebuild when unrelated files (like templates) change. #120
- The
@localClassName
decorator now properly works with getters across various Babel and TypeScript versions. #118
- We're now using
broccoli-postcss@4
(which itself usespostcss@7
) forpostprocess
plugins. This should be a non-breaking change for our usage in this addon. #124
- Elements with both
local-class
and...attributes
should no longer lose their local class when an externalclass
orlocal-class
is passed in. #116
The 1.0 release should largely be a drop-in replacement coming from 0.7.x, but there are a few changes to be aware of:
- Referencing a
local-class
in a template that doesn't have a correspondingstyles
module is now a hard error (before it would silently fail and add no class to the target element). - Using
localClassNames
orlocalClassNameBindings
on a component with no template is no longer possible. You can either create an empty template for that component or import the styles module and setclassNames
orclassNameBindings
using the imported mapping, e.g.classNames: styles['my-local-class']
.
- The type declaration for
localClassNames
now uses the right identifier - The error message when referencing a
local-class
in a template with no styles module is now more informative
If you're migrating from 0.7.x, see the release notes for the 1.0 betas below for additional changes and fixes.
- The long awaited
@localClassNames
and@localClassName
decorators, which work as parallels toember-decorators
'@classNames
and@className
, are now available.
- Turns out there was one breaking change from the 0.7 series: components must now have a template in order for their
localClassNames
andlocalClassNameBindings
(as well as the decorator versions) to resolve. The error message for this scenario has been improved to provide more actionable details.
This release is the first beta for Ember CSS Modules 1.0. There are no known breaking changes since 0.7.10, but as described below, there were a few internal refactorings, so we'll run a beta series before christening the official 1.0 🎉
addPostcssPlugin
now accepts multiple arguments (#103)
- The
template-only-glimmer-components
feature should no longer conflict with ember-css-modules (#98)
- The majority of the runtime monkeypatching that was present in this addon has been removed in favor of build-time processing. The only remaining runtime code is the
{{local-class}}
helper and an extension to theComponent
class to supportlocalClassNames
andlocalClassNameBindings
. (#99)
- Support importing styles via
@value
andcomposes:
from addons with@scope
ed names.
- Ember 3.1 ships with a version of Glimmer that expects AST transforms to use a singular
visitor
key rather than pluralvisitors
. So we do that. Big thanks to @luqman for tracking this down. - The internal computed property we set up to support
localClassNameBindings
now uses Ember'sdefineProperty
for compatibility with the ES5 getters overhaul.
- Nothing. This was essentially a no-op republish of 0.7.7.
- Prerelease versions of Ember CLI are correctly detected now.
- The plugin system now supports a notion of lint plugins, which will activate for developing addons even when they're in
devDependencies
.
- The
local-class
template transform should now play nicely with ember-font-awesome's own transforms (thanks @buschtoens!) - The plugin registry no longer explodes when addons with no package keywords are present (thanks @devotox!)
- The ability to use
{{local-class}}
to inject classes from other modules is now public and documented (thanks @kellyselden!)
localClassNameBindings
now works with string values instead of just booleans (thanks @luxferresum!)headerFiles
andfooterFiles
will now accept file paths with and without extensions- Setup for
localClassNames
andlocalClassNameBindings
now short circuits to avoid extra work for tagless components (thanks @garno!)
- PostCSS plugins can now be specified to run against the final concatenated output of all modules using the
postprocess
array (thanks @alexlafroscia!)
- During testing,
import 'ember-css-modules/extensions'
is no longer required to have styles function correctly in integration tests. - When no styles for a component can be found,
localClassNameBindings
now silently binds no classes instead of throwing an error.
- Modules to be included at the top or bottom of the concatenated output can now be set via the
headerModules
andfooterModules
configuration options. See the module ordering guide for details.
@after-module
has been deprecated in favor of the newheaderModules
/footerModules
configuration
- Support for Ember 2.15's new form factor for template AST transforms has been added.
- Styles resolution for components and controllers no longer assumes only a single
:
in container keys.
- An initial cut of a plugin system has been implemented, allowing common PostCSS plugin sets, shared configuration, and other bits of reusable code to be packaged up and redistributed. See the README for a few implemented examples.
- The CSS Modules pipeline has been upgraded and now uses PostCSS 6
- Some of the more advanced topics in the README have been broken out into dedicated mini-guides in an effort to keep the main document from being so overwhelming
- Attempting to pull styles from an addon that doesn't exist now provides a useful error message (#65).
- There have been some internal changes to how styles are read from the app/addon trees. This should be a non-breaking change (and fixes a number of oddities, including previous incompatibility with lazy engines), but is enough of a shift to warrant a version bump and a note.
- Attempting to import a nonexistent
@value
orcompose
a nonexistent class is now a hard error at build time.
- Support for the deprecated
styles
property has been removed.
- The (deprecated) computed
styles
property is no longer read-only, to allow for other component APIs that expect something with that name to be passed in. - Avoid repurposing
this.options
in the addon to support Ember CLI 2.12 (#64)
- Now actually avoid triggering the ember-getowner-polyfill deprecation notice.
- This addon will now run before ember-cli-postcss, enabling cooperative preprocessing as with ember-cli-sass and friends (#58).
- Upgraded ember-getowner-polyfill and eliminated a deprecation warning from its changed usage.
- Null local class values, e.g.
local-class={{if false 'foo'}}
no longer result in an exception (#57).
- Removed a spurious warning when specifying a local-class for a component that doesn't yet have styles.
- Mirroring the
local-class
attribute, there is now alocal-class
helper that can be used in templates to reference local classnames e.g. when passing them to child components as properties.
- In the past, attempting to import a nonexistent class or value would silently fail. This behavior is now deprecated and will be a hard error in the future.
- Usage of the
styles
computed property on components and controllers is now deprecated.- In templates, you can replace
{{styles.class-name}}
with{{local-class 'class-name'}}
. - In JavaScript code, you can import the styles object via a normal ES2015
import
. - As a migration stepping stone, you can import the styles object and set it on your component/controller's prototype to mimic the old form factor:
import styles from './styles'; export default Ember.Component.extend({ styles, // ... });
- In templates, you can replace
- Support for Ember 1.13 has been removed; ember-css-modules now supports Ember 2.0+.
- Source maps can now be generated for applications, with caveats. See the README and ember-cli/broccoli-concat#58 for details.
- A warning is now issued for addons that have no
addon/styles
directory, since Ember CLI won't invoke registered CSS preprocessors in that scenario.
- Fewer files are
require
d when ember-css-modules loads, lessening the overall impact it should have on Ember CLI's startup time
- Windows is now fully supported (#52).
localClassNameBindings
now works with classes that usecomposes
(#48).
- Virtual modules that export constants can be configured at build time.
- The configured modules extension can now contain a
.
(see #41 for history)
- The
local-class
attribute now accepts dynamic values (#40) - Components may specify
localClassNames
andlocalClassNameBindings
, similar toclassNames
andclassNameBindings
respectively, to bind local classes to their root elements (#26)
- Values with commas and quotes can now be exposed in modules (#22)
- The beginnings of support for
@value
andcomposes:
from addons, with some caveats. Real documentation forthcoming once the feature has a little time to bake.
- Provide caching information for
ember-cli-htmlbars
so it can correctly invalidate when the plugin changes.
- Preliminary support for Glimmer 2 with the Ember alpha series.
- Local class names can be specified via the
local-class
attribute (#31) - PostCSS options such as custom syntax are passed through via
postcssOptions
config (#34) - The default extension for modules can be specified via
extension
config (#34)
- An
intermediateOutputPath
may be specified in order to have ember-css-modules emit to a location other than<app-name>.css
, leaving other files in the styles tree untouched for further processing (#28). See the README for further details on how this in combination with the changes in #34 allow for working alongside other CSS preprocessors.
_super
is now properly called in the addoninit()
to avoid a deprecation notice
0.3.2 Hidden Gems (May 1, 2016)
- Hidden files (e.g.
.DS_Store
) no longer break the build process (#21)
- Final linking of
@value
s now occurs before other PostCSS plugins execute (#23)
- Classes named
container
can be used once again (#15)
- Modules are now more intelligently ordered in the final output by default, according to composition and value dependencies. See the README for further details.
- Ability to override scoped name generation (#3)
- Greater (explicit) control over module ordering in final output (#7)
- Handle component lookup changes in Ember 2.5+ without crashing
- Pass through non-CSS files in the styles tree (#13)
- Don't rely on custom registry options set up in an initializer (#14)