Skip to content

Refactor asset management: Migrate from Bower to NPM for package dependencies and update related documentation. #20368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/ci-node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ jobs:
- name: Install dependencies.
run: composer update $DEFAULT_COMPOSER_FLAGS

- name: Install JQuery `3.6.*@stable` for tests.
run: composer require "bower-asset/jquery:3.6.*@stable"

- name: Install node.js.
uses: actions/setup-node@v4
with:
Expand Down
12 changes: 1 addition & 11 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,7 @@
"lib-pcre": "*",
"yiisoft/yii2-composer": "~2.0.4",
"ezyang/htmlpurifier": "^4.17",
"cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0",
"bower-asset/jquery": "3.7.*@stable | 3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
"bower-asset/inputmask": "^5.0.8 ",
"bower-asset/punycode": "^2.2",
"bower-asset/yii2-pjax": "~2.0.1"
"cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0"
},
"require-dev": {
"cebe/indent": "~1.0.2",
Expand All @@ -87,12 +83,6 @@
"phpunit/phpunit": "9.6",
"yiisoft/yii2-coding-standards": "^3.0"
},
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
}
],
"suggest": {
"yiisoft/yii2-coding-standards": "you can use this package to check for code style issues when contributing to yii"
},
Expand Down
93 changes: 8 additions & 85 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions docs/guide/concept-aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ Yii predefines a set of aliases to easily reference commonly used file paths and
containing the [entry script](structure-entry-scripts.md).
- `@web`, the base URL of the currently running Web application. It has the same value as [[yii\web\Request::baseUrl]].
- `@vendor`, the [[yii\base\Application::vendorPath|Composer vendor directory]]. Defaults to `@app/vendor`.
- `@bower`, the root directory that contains [bower packages](https://bower.io/). Defaults to `@vendor/bower`.
- `@npm`, the root directory that contains [npm packages](https://www.npmjs.com/). Defaults to `@vendor/npm`.
- `@npm`, the root directory that contains [npm packages](https://www.npmjs.com/). Defaults to `@app/node_modules`.

The `@yii` alias is defined when you include the `Yii.php` file in your [entry script](structure-entry-scripts.md).
The rest of the aliases are defined in the application constructor when applying the application
Expand Down
21 changes: 3 additions & 18 deletions docs/guide/start-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,11 @@ But there are other installation options available:
Installing Assets <span id="installing-assets"></span>
-----------------

Yii relies on [Bower](https://bower.io/) and/or [NPM](https://www.npmjs.com/) packages for the asset (CSS and JavaScript) libraries installation.
It uses Composer to obtain these libraries, allowing PHP and CSS/JavaScript package versions to resolve at the same time.
This can be achieved either by usage of [asset-packagist.org](https://asset-packagist.org) or [composer asset plugin](https://github.com/fxpio/composer-asset-plugin).
Please refer to [Assets documentation](structure-assets.md) for more details.

You may want to either manage your assets via native Bower/NPM client, use CDN or avoid assets installation entirely.
In order to prevent assets installation via Composer, add the following lines to your 'composer.json':

```json
"replace": {
"bower-asset/jquery": ">=1.11.0",
"bower-asset/inputmask": ">=3.2.0",
"bower-asset/punycode": ">=1.3.0",
"bower-asset/yii2-pjax": ">=2.0.0"
},
```
Yii relies on [NPM](https://www.npmjs.com/) packages for the asset (CSS and JavaScript) libraries installation.

> Note: in case of bypassing asset installation via Composer, you are responsible for the assets installation and resolving
> version collisions. Be prepared for possible inconsistencies among asset files from different extensions.
Please refer to [Assets documentation](structure-assets.md) for more details.

You may want to either manage your assets via native NPM client, use CDN or avoid assets installation entirely.

Verifying the Installation <span id="verifying-installation"></span>
--------------------------
Expand Down
61 changes: 5 additions & 56 deletions docs/guide/structure-assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ use yii\web\AssetBundle;

class FontAwesomeAsset extends AssetBundle
{
public $sourcePath = '@bower/font-awesome';
public $sourcePath = '@npm/font-awesome';
public $css = [
'css/font-awesome.min.css',
];
Expand All @@ -205,13 +205,9 @@ The above example defines an asset bundle for the ["fontawesome" package](https:
the `only` publishing option, only the `fonts` and `css` subdirectories will be published.


### Bower and NPM Assets installation <span id="bower-npm-assets"></span>
### NPM Assets installation <span id="npm-assets"></span>

Most JavaScript/CSS packages are managed by [Bower](https://bower.io/) and/or [NPM](https://www.npmjs.com/) package
managers. In PHP world we have Composer, that manages PHP dependencies, but it is possible to load
both Bower and NPM packages using `composer.json` just as PHP packages.

To achieve this, we should configure our composer a bit. There are two options to do that:
Most JavaScript/CSS packages are managed by [NPM](https://www.npmjs.com/) package managers.

___

Expand All @@ -233,67 +229,20 @@ In the `composer.json` of your project, add the following lines:
]
```

Adjust `@npm` and `@bower` [aliases](concept-aliases.md) in you [application configuration](concept-configurations.md):
Adjust `@npm` [aliases](concept-aliases.md) in you [application configuration](concept-configurations.md):

```php
$config = [
...
'aliases' => [
'@bower' => '@vendor/bower-asset',
'@npm' => '@vendor/npm-asset',
'@npm' => '@root/npm-asset',
],
...
];
```

Visit [asset-packagist.org](https://asset-packagist.org) to know, how it works.

#### Using fxp/composer-asset-plugin

Compared to asset-packagist, composer-asset-plugin does not require any changes to application config. Instead, it
requires global installation of a special Composer plugin by running the following command:

```bash
composer global require "fxp/composer-asset-plugin:^1.4.1"
```

This command installs [composer asset plugin](https://github.com/fxpio/composer-asset-plugin/) globally
which allows managing Bower and NPM package dependencies through Composer. After the plugin installation,
every single project on your computer will support Bower and NPM packages through `composer.json`.

Add the following lines to `composer.json` of your project to adjust directories where the installed packages
will be placed, if you want to publish them using Yii:

```json
"config": {
"fxp-asset": {
"installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
}
}
```

> Note: `fxp/composer-asset-plugin` significantly slows down the `composer update` command in comparison
to asset-packagist.

____

After configuring Composer to support Bower and NPM:

1. Modify the `composer.json` file of your application or extension and list the package in the `require` entry.
You should use `bower-asset/PackageName` (for Bower packages) or `npm-asset/PackageName` (for NPM packages)
to refer to the library.
2. Run `composer update`
3. Create an asset bundle class and list the JavaScript/CSS files that you plan to use in your application or extension.
You should specify the [[yii\web\AssetBundle::sourcePath|sourcePath]] property as `@bower/PackageName` or `@npm/PackageName`.
This is because Composer will install the Bower or NPM package in the directory corresponding to this alias.

> Note: Some packages may put all their distributed files in a subdirectory. If this is the case, you should specify
the subdirectory as the value of [[yii\web\AssetBundle::sourcePath|sourcePath]]. For example, [[yii\web\JqueryAsset]]
uses `@bower/jquery/dist` instead of `@bower/jquery`.


## Using Asset Bundles <span id="using-asset-bundles"></span>

Expand Down
29 changes: 14 additions & 15 deletions docs/guide/structure-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,31 +181,30 @@ can know which extensions are installed (the information can be accessed via [[y

Your extension depends on Yii (of course). So you should list it (`yiisoft/yii2`) in the `require` entry in `composer.json`.
If your extension also depends on other extensions or third-party libraries, you should list them as well.
Make sure you also list appropriate version constraints (e.g. `1.*`, `@stable`) for each dependent package. Use stable
dependencies when your extension is released in a stable version.
Make sure you also list appropriate version constraints (for example, `1.*`, `@stable`) for each dependent package.
Use stable dependencies when your extension is released in a stable version.

Most JavaScript/CSS packages are managed using [Bower](https://bower.io/) and/or [NPM](https://www.npmjs.com/),
instead of Composer. Yii uses the [Composer asset plugin](https://github.com/fxpio/composer-asset-plugin)
to enable managing these kinds of packages through Composer. If your extension depends on a Bower package, you can
simply list the dependency in `composer.json` like the following:
For JavaScript/CSS packages, Yii uses [NPM](https://www.npmjs.com/) natively. If your extension depends on NPM packages,
you should include a `package.json` file in your extension root directory. For example:

```json
{
// package dependencies
"require": {
"bower-asset/jquery": ">=1.11.*"
"name": "your-extension-name",
"version": "1.0.0",
"dependencies": {
"jquery": "^3.6.0",
"bootstrap": "^5.1.3"
}
}
```

The above code states that the extension depends on the `jquery` Bower package. In general, you can use
`bower-asset/PackageName` to refer to a Bower package in `composer.json`, and use `npm-asset/PackageName`
to refer to a NPM package. When Composer installs a Bower or NPM package, by default the package content will be
installed under the `@vendor/bower/PackageName` and `@vendor/npm/Packages` directories, respectively.
These two directories can also be referred to using the shorter aliases `@bower/PackageName` and `@npm/PackageName`.
When your extension is installed, users will need to run `npm install` in the extension directory to install these
frontend dependencies. You should document this requirement in your extension's README file.

For more details about asset management, please refer to the [Assets](structure-assets.md#bower-npm-assets) section.
In your extension's code, you can reference these assets from the `node_modules` directory. For example, in an asset
bundle class:

For more details about asset management, please refer to the [Assets](structure-assets.md#npm-assets) section.

#### Class Autoloading <span id="class-autoloading"></span>

Expand Down
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Yii Framework 2 Change Log

- Chg #19902: Remove support for CUBRID (mtangoo)
- Chg #19891: Remove XCache and ZendDataCache support (mtangoo)
- Enh #20368: Refactor asset management: Migrate from `Bower` to `NPM` for package dependencies and update related documentation (terabytesoftw)


2.0.53 under development
Expand Down
3 changes: 1 addition & 2 deletions framework/base/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,7 @@ public function setVendorPath($path)
{
$this->_vendorPath = Yii::getAlias($path);
Yii::setAlias('@vendor', $this->_vendorPath);
Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower');
Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm');
Yii::setAlias('@npm', $this->getBasePath() . DIRECTORY_SEPARATOR . 'node_modules');
}

/**
Expand Down
6 changes: 1 addition & 5 deletions framework/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@
"lib-pcre": "*",
"yiisoft/yii2-composer": "~2.0.4",
"ezyang/htmlpurifier": "^4.17",
"cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0",
"bower-asset/jquery": "3.7.*@stable | 3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
"bower-asset/inputmask": "^5.0.8 ",
"bower-asset/punycode": "^1.4",
"bower-asset/yii2-pjax": "~2.0.1"
"cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0"
},
"autoload": {
"psr-4": {"yii\\": ""}
Expand Down
2 changes: 1 addition & 1 deletion framework/validators/PunycodeAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
class PunycodeAsset extends AssetBundle
{
public $sourcePath = '@bower/punycode';
public $sourcePath = '@npm/punycode';
public $js = [
'punycode.js',
];
Expand Down
Loading