diff --git a/pages/guides/core-workflows/asset-management.md b/pages/guides/core-workflows/asset-management.md new file mode 100644 index 0000000..934afe3 --- /dev/null +++ b/pages/guides/core-workflows/asset-management.md @@ -0,0 +1,828 @@ +--- +authors: skipjack,michael-ciniawsky,TheDutchCoder,sudarsangp,chenxsan,EugeneHlushko,AnayaDesign,wizardofhogwarts,astonizer,snitin315,Brennvo,mr-baraiya,avivkeller +--- + +# Asset Management + +If you've followed the guides from the beginning, you now have a small project that prints "Hello webpack". The next step is to bring in other kinds of assets, such as images, and see how webpack handles them. + +Before webpack, front-end developers relied on tools like [grunt](https://gruntjs.com/) and [gulp](https://gulpjs.com/) to process assets and copy them from a `/src` folder into a `/dist` or `/build` directory. JavaScript modules followed the same approach, but webpack takes it further: it **dynamically bundles** every dependency, building what's known as a [dependency graph](/guides/getting-started/concepts/dependency-graph). This is powerful because each module now _explicitly declares its dependencies_, which lets webpack skip anything that isn't actually used. + +One of webpack's nicest features is that you can _import almost any type of file_, not just JavaScript, as long as there's a loader or built-in [Asset Modules](/guides/core-workflows/asset-modules) support for it. That means the benefits you get with JavaScript, like explicit dependencies, apply to everything you use to build a site or web app. We'll begin with CSS, since that setup is probably already familiar to you. + +## Setup + +First, make a small change to the project before we begin. + +```diff displayName="dist/index.html" + + + + +- Getting Started ++ Asset Management + + +- ++ + + +``` + +```diff displayName="webpack.config.js" + import path from 'node:path'; + import { fileURLToPath } from 'node:url'; + + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + + export default { + entry: './src/index.js', + output: { +- filename: 'main.js', ++ filename: 'bundle.js', + path: path.resolve(__dirname, 'dist'), + }, + }; +``` + +## Loading CSS + +To `import` a CSS file from within a JavaScript module, install the [style-loader](/docs/loaders/style-loader) and [css-loader](/docs/loaders/css-loader), then add them to your [`module` configuration](#TODO[/configuration/module]): + +```bash +npm install --save-dev style-loader css-loader +``` + +```diff displayName="webpack.config.js" + import path from 'node:path'; + import { fileURLToPath } from 'node:url'; + + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + + export default { + entry: './src/index.js', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist'), + }, ++ module: { ++ rules: [ ++ { ++ test: /\.css$/i, ++ use: ['style-loader', 'css-loader'], ++ }, ++ ], ++ }, + }; +``` + +Loaders can be chained together, with each loader in the chain transforming the resource it receives. The chain runs in reverse order, from right to left. + +For example, consider the following rule: + +```js +export default { + module: { + rules: [ + { + test: /\.scss$/i, + use: ['postcss-loader', 'sass-loader'], + }, + ], + }, +}; +``` + +Although `postcss-loader` is listed before `sass-loader` in the `use` array, webpack executes `sass-loader` first to compile Sass into CSS, then runs `postcss-loader` on the result. If this order isn't respected, webpack may throw errors. + +```diff displayName="project" + webpack-demo + ├── package.json + ├── package-lock.json + ├── webpack.config.js + ├── /dist + │ ├── bundle.js + │ └── index.html + ├── /src ++ │ ├── style.css + │ └── index.js + └── /node_modules +``` + +```css displayName="src/style.css" +.hello { + color: red; +} +``` + +```diff displayName="src/index.js" + import _ from 'lodash'; ++import './style.css'; + + function component() { + const element = document.createElement('div'); + + // Lodash, now imported by this script + element.innerHTML = _.join(['Hello', 'webpack'], ' '); ++ element.classList.add('hello'); + + return element; + } + + document.body.appendChild(component()); +``` + +Now run the build command: + +```bash +$ npm run build + +... +[webpack-cli] Compilation finished +asset bundle.js 72.6 KiB [emitted] [minimized] (name: main) 1 related asset +runtime modules 1000 bytes 5 modules +orphan modules 326 bytes [orphan] 1 module +cacheable modules 539 KiB + modules by path ./node_modules/ 538 KiB + ./node_modules/lodash/lodash.js 530 KiB [built] [code generated] + ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js 6.67 KiB [built] [code generated] + ./node_modules/css-loader/dist/runtime/api.js 1.57 KiB [built] [code generated] + modules by path ./src/ 965 bytes + ./src/index.js + 1 modules 639 bytes [built] [code generated] + ./node_modules/css-loader/dist/cjs.js!./src/style.css 326 bytes [built] [code generated] +webpack 5.x.x compiled successfully in 2231 ms +``` + +Open `dist/index.html` in your browser again and you should see `Hello webpack` styled in red. To check what webpack did, inspect the page rather than viewing the page source; the source won't reflect the result because the `