Skip to content

Commit

Permalink
Update webpack page
Browse files Browse the repository at this point in the history
  • Loading branch information
lcharette committed Apr 20, 2024
1 parent b0b9323 commit 6486ad6
Showing 1 changed file with 30 additions and 17 deletions.
47 changes: 30 additions & 17 deletions pages/13.asset-management/01.webpack-encore/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ taxonomy:
category: docs
---

In a minimalistic setup, asset retrieval is fairly straightforward. We might just keep all of our Javascript files in a `js/` directory directly under our public document root directory. Then the URL is simply `http://example.com/js/whatever.js`, and our webserver matches the _URL path_ `/js/whatever.js` to the _filesystem_ path `/path/to/document/root/js/whatever.js`, and places the contents of that file in the HTTP response. In most web servers this happens so transparently, that a lot of new developers assume that they're somehow giving direct access to the server's file system. In reality the web server is mediating the interaction, and generating an HTTP response using the _contents_ of these files.
In a minimalistic setup, asset retrieval is fairly straightforward. We might just keep all of our Javascript files in a `js/` directory directly under our public document root directory. Then the URL is simply `http://example.com/js/whatever.js`, the web server matches the _URL path_ `/js/whatever.js` to the _filesystem_ path `/path/to/document/root/public/js/whatever.js` and finally places the contents of that file in the HTTP response. In most web servers, this happens so transparently that a lot of new developers assume that they're somehow giving direct access to the server's file system. In reality the web server is mediating the interaction, and generating an HTTP response using the _contents_ of these files.

In UserFrosting, the Sprinkle system makes this a little more complicated. Each Sprinkle can contribute its own assets to the application (typically under a `app/assets/` subdirectory), and it should be possible for a Sprinkle to override assets in another Sprinkle that was loaded earlier in the stack. Plus, since the Sprinkle is not part of our code, but loaded as a normal dependency, the assets can be hard to locate.
In UserFrosting, the Sprinkle system makes this a little more complicated. Each Sprinkle can contribute their own assets to the application (typically under a `app/assets/` subdirectory), and it should be possible for a Sprinkle to override assets in another Sprinkle that was loaded earlier in the stack. Plus, since the Sprinkle is not part of our code, but loaded as an **npm** dependency, the assets can be hard to locate.

Modern frameworks and languages also complicate things. For example, [Vue.js](https://vuejs.org), [React](https://react.dev), [Sass](https://sass-lang.com) and [Less](https://lesscss.org) requires a building or compilation step, powered by npm and Node.js scripts. Third party packages can be managed through npm, similar to how Composer manage PHP dependencies.
Modern frameworks also complicate things. For example, [Vue.js](https://vuejs.org), [React](https://react.dev), [Sass](https://sass-lang.com) and [Less](https://lesscss.org) requires a bundling or compilation step. Finally, third party dependencies can be managed through npm, similar to how Composer manage PHP dependencies, and are not known to UserFrosting PHP backend.

For these reasons, UserFrosting makes use of **Symfony's [Webpack Encore](https://github.com/symfony/webpack-encore)** to handle all frontend related task. Webpack Encore is a simpler way to integrate [Webpack](https://webpack.js.org). It provides a clean & powerful API for bundling JavaScript modules, pre-processing CSS & JS and compiling and minifying assets.
For these reasons, UserFrosting uses **Symfony's [Webpack Encore](https://github.com/symfony/webpack-encore)** to handle all frontend related task. Webpack Encore is a simpler way to integrate [Webpack](https://webpack.js.org). It provides a clean & powerful API for bundling JavaScript modules, pre-processing CSS & JS and compiling and minifying assets, and provides the necessary integration in the Twig template system.

Compiling assets through Webpack Encore basically does :

1. It copies statics assets from individual Sprinkles to the public web directory, so that they can be served directly by the web server instead of having to go through UserFrosting;
2. It concatenates assets within each asset entries into a single file, reducing the number of requests that the client needs to make. This makes the page load more quickly for the client;
2. It uses entry files to bundle together assets for a specific use into a single file, reducing the number of requests the browser needs to make. This makes the page load more quickly for the client;
3. It can process Sass or Less files into a compiled css file;
4. It can process Vue and React files;
5. It [minifies](https://en.wikipedia.org/wiki/Minification_(programming)) CSS and Javascript assets, so that they are smaller and can be loaded more quickly by the client;
6. In production, enables versioning of each assets file, to better manage caching by the browser;
4. It can build Vue and React files;
5. It [minifies](https://en.wikipedia.org/wiki/Minification_(programming)) CSS and Javascript assets, so that they are smaller and can be loaded more quickly by the browser;
6. In production, it enables versioning of each assets file, to better manage caching by the browser;
7. And so much more.

## Npm and `packages.json`
Expand All @@ -37,8 +37,8 @@ Where Composer has it's `composer.json` file to defines the project dependencies
```json
{
"dependencies": {
"sprinkle-admin": "github:userfrosting/sprinkle-admin",
"theme-adminlte": "github:userfrosting/theme-adminlte"
"@userfrosting/sprinkle-admin": "~5.1.0",
"@userfrosting/theme-adminlte": "~5.1.0"
},
"devDependencies": {
"@symfony/webpack-encore": "^4.4.0",
Expand All @@ -55,11 +55,9 @@ Where Composer has it's `composer.json` file to defines the project dependencies
}
```

1. **dependencies** : These are the client dependencies, which are will eventually be passed to the Browser. For example, _JQuery_ is a dependencies, as it will be used by the browser;
2. **devDependencies** : These are CLI dependencies. They are required to run the building process;
3. **scripts** : npm command alias for dependencies commands.
**Dependencies** are the your app frontend dependencies, which are will eventually be passed to the browser. For example, _JQuery_ can be a dependencies, as it will be used by the browser. **devDependencies** are CLI dependencies. They are required to run the building process. Finally, **scripts** are npm command alias.

In the example above, you can see both the *Admin Sprinkle* and *AdminLTE Theme* are included as dependencies. While theses are also included by Composer, it's necessary to include them also here, so their assets can be accessed by npm and Webpack Encore. The dev dependencies includes, among others, Webpack Encore. It will then be installed when running `npm install`, `php bakery assets:build` or `php bakery assets:install`. Finally, the *scripts* section expose the encore build tasks.
In the example above, you can see both the *Admin Sprinkle* and *AdminLTE Theme* are included as dependencies. While theses are also included by Composer, it's necessary to also include them here, because their assets will be accessed by npm and Webpack Encore command, and npm commands, written in JavaScript can't access Composer PHP dependencies. The dev dependencies includes, among others, Webpack Encore. Of course, each of these dependencies also have their own "sub dependencies", just like with Composer. All of these dependencies will be installed when running `npm install`, `php bakery assets:build` or `php bakery assets:install`. Finally, the *scripts* section expose the encore build tasks.

Dependencies installation will be automatically handled by the `php bakery bake` or `php bakery assets:build` commands. Alternatively, you can still uses the typical npm commands from the command line:

Expand Down Expand Up @@ -90,8 +88,8 @@ const Encore = require('@symfony/webpack-encore');

// List dependent sprinkles and local entries files
const sprinkles = {
AdminLTE: require('theme-adminlte/webpack.entries'),
Admin: require('sprinkle-admin/webpack.entries'),
AdminLTE: require('@userfrosting/theme-adminlte/webpack.entries'),
Admin: require('@userfrosting/sprinkle-admin/webpack.entries'),
App: require('./webpack.entries')
}

Expand Down Expand Up @@ -166,11 +164,26 @@ Encore

// uncomment if you're having problems with a jQuery plugin
.autoProvidejQuery()

// uncomment if you use React
//.enableReactPreset()
;

module.exports = Encore.getWebpackConfig();
```

We will learn in the next pages about entry files. For now, it's only important to note the following block :

```js
const sprinkles = {
AdminLTE: require('@userfrosting/theme-adminlte/webpack.entries'),
Admin: require('@userfrosting/sprinkle-admin/webpack.entries'),
App: require('./webpack.entries')
}
```

This is a list of dependent sprinkles entry files list, plus our own list. Every time you add a new sprinkle, you might need to add it's `webpack.entries` to this list. Also notice how the `.js` extension of the actual file reference is omitted, which is totally fine as it's a feature of Node.js.

## Compiling assets

To build the assets, run the following [Bakery command](/cli/commands#assets:build) :
Expand All @@ -191,7 +204,7 @@ $ php bakery assets:build --watch
$ php bakery assets:webpack --watch
```

[notice=warning]Whenever you make changes in your `webpack.config.js` file, you must stop and restart encore when using the "watch" option.[/notice]
[notice=warning]Whenever you make changes in your `webpack.config.js` or `webpack.entries.js` file, you must stop and restart encore when using the "watch" option.[/notice]

To compile assets for a **production** environment, simply use:

Expand Down

0 comments on commit 6486ad6

Please sign in to comment.