Extending with Plugins - SurviveJS [PDF]

Unlike for loaders, there is no separate environment where you can run plugins so you have to run them against webpack i

4 downloads 73 Views 256KB Size

Recommend Stories


Netbeans pdf plugins - PDFStone.com [PDF]
Download ebook pdf Netbeans pdf plugins ~ We have made it easy for you to find a PDF. Ebooks without any digging. And by ... finding Netbeans pdf plugins, you are right to find our website which has a comprehensive collection of manuals listed. Our l

Moodle plugins directory: Lesson PDF Export [PDF]
Regarding your issue, do you want the PDF to include the answers the student submitted? This could prove problematic, given how TCPDF writes HTML but it's not impossible, I imagine it might cause some issues if I start writing code that touches more

AvediaPlayer Plugins
Every block of stone has a statue inside it and it is the task of the sculptor to discover it. Mich

Extending Planning & Forecasting with Analytics
I cannot do all the good that the world needs, but the world needs all the good that I can do. Jana

Extending XQuery with Window Functions
The happiest people don't have the best of everything, they just make the best of everything. Anony

Extending dataflows with temporal graphs
Everything in the universe is within you. Ask all from yourself. Rumi

Extending Fortran with Meta-programming
You're not going to master the rest of your life in one day. Just relax. Master the day. Than just keep

Wordpress THEMES et PLUGINS
In the end only three things matter: how much you loved, how gently you lived, and how gracefully you

Em Temas e Plugins
I tried to make sense of the Four Books, until love arrived, and it all became a single syllable. Yunus

Extending Probe Card Life with Tip
Do not seek to follow in the footsteps of the wise. Seek what they sought. Matsuo Basho

Idea Transcript


HOME

READ THE BLOG

MAINTENANCE BOOK

WEBPACK BOOK

REACT BOOK

HIRE ME

@SURVIVEJS

Extending with Plugins

qimono (Public Domain)

Search

lint-staged - Run Linters on git Staged Files - Interview with Andrey Okonetchnikov

Table of Contents Compared to loaders, plugins are a more flexible means to extend webpack. You have access to webpack's compiler and compilation processes. It's possible to run child compilers, and plugins can work in tandem with loaders as ExtractTextPlugin

Foreword Preface Introduction

shows.

What is Webpack Plugins allow you to intercept webpack's execution through hooks. Webpack itself has been implemented as a collection of plugins. Underneath it relies on tapable plugin interface that allows webpack to apply plugins in different ways.

Developing Getting Started webpack-dev-server

You'll learn to develop a couple of small plugins next. Unlike for loaders, there is no separate environment where you can run plugins, so you have to run them against webpack itself. It's possible to push smaller logic outside of the webpack facing portion, though, as this allows you to unit test it in isolation.

Composing Configuration Styling Loading Styles Separating CSS Eliminating Unused CSS

The Basic Flow of Webpack Plugins

Autoprefixing

A webpack plugin is expected to expose an apply(compiler) method. JavaScript

Loading Assets

allows multiple ways to do this. You could use a function and then attach methods to its prototype . To follow the newest syntax, you could use a class to model the

Loader Definitions

same idea.

Loading Images Loading Fonts

Regardless of your approach, you should capture possible options passed by a user at the constructor. It's a good idea to declare a schema to communicate them to the user. schema-utils allows validation and works with loaders too.

Loading JavaScript Building Source Maps

When the plugin is connected to webpack configuration, webpack will run its constructor and call apply with a compiler object passed to it. The object exposes

Bundle Splitting

webpack's plugin API and allows you to use its hooks as listed by the official compiler reference.

Code Splitting Tidying Up Optimizing

webpack-defaults works as a starting point for webpack plugins. It contains the

Minifying

infrastructure used to develop official webpack loaders and plugins.

Tree Shaking Environment Variables

Setting Up a Development Environment

Adding Hashes to Filenames

Since plugins have to be run against webpack, you have to set up one to run a demo plugin that will be developed further:

Separating a Manifest Build Analysis Performance

webpack.plugin.js

Output const path = require("path");

Build Targets

const DemoPlugin = require("./plugins/demo-plugin.js");

Multiple Pages

const PATHS = { lib: path.join(__dirname, "app", "shake.js"), build: path.join(__dirname, "build"), };

Server Side Rendering Techniques Dynamic Loading

module.exports = { entry: { lib: PATHS.lib, }, output: { path: PATHS.build, filename: "[name].js", }, plugins: [new DemoPlugin()], };

Web Workers Internationalization Testing Deploying Applications Consuming Packages Extending Extending with Loaders

If you don't have a lib entry file set up yet, write one. The contents don't matter

Extending with Plugins

as long as it's JavaScript that webpack can parse.

Conclusion Appendices

To make it convenient to run, set up a build shortcut:

Comparison of Build Tools package.json

Hot Module Replacement CSS Modules

"scripts": {

Searching with React

"build:plugin": "webpack --config webpack.plugin.js", ... },

Troubleshooting Glossary

Executing it should result in an Error: Cannot find module failure as the actual plugin is still missing.

If you want an interactive development environment, consider setting up nodemon against the build. Webpack's watcher won't work in this case.

Implementing a Basic Plugin The simplest plugin should do two things: capture options and provide apply method: plugins/demo-plugin.js module.exports = class DemoPlugin { apply() { console.log("applying"); } };

If you run the plugin ( npm run build:plugin ), you should see applying message at the console. Given most plugins accept options, it's a good idea to capture those and pass them to apply .

Capturing Options Options can be captured through a constructor : plugins/demo-plugin.js module.exports = class DemoPlugin { constructor(options) { this.options = options; } apply() { console.log("apply", this.options); } };

Running the plugin now would result in apply undefined kind of message given no options were passed. Adjust the configuration to pass an option: webpack.plugin.js module.exports = { ... plugins: [new DemoPlugin()], plugins: [new DemoPlugin({ name: "demo" })], ], };

Now you should see apply { name: 'demo' } after running.

Understanding Compiler and Compilation apply receives webpack's compiler as a parameter. Adjust as below:

plugins/demo-plugin.js module.exports = class DemoPlugin { constructor(options) { this.options = options; } apply(compiler) { console.log(compiler); } };

After running, you should see a lot of data. Especially options should look familiar as it contains webpack configuration. You can also see familiar names like records . If you go through webpack's plugin development documentation, you'll see a compiler provides a large number of hooks. Each hook corresponds to a specific stage. For example, to emit files, you could listen to the emit event and then write. Change the implementation to listen and capture compilation : plugins/demo-plugin.js module.exports = class DemoPlugin { constructor(options) { this.options = options; } apply(compiler) { console.log(compiler); compiler.plugin("emit", (compilation, cb) => { console.log(compilation); cb(); }); } };

Forgetting the callback and running the plugin makes webpack fail silently!

Running the build should show more information than before because a compilation object contains whole dependency graph traversed by webpack. You have access to everything related to it here including entries, chunks, modules, assets, and more.

Many of the available hooks expose compilation, but sometimes they reveal a more specific structure, and it takes a more particular study to understand those.

Loaders have dirty access to compiler and compilation through underscore ( this._compiler / this._compilation ).

Writing Files Through Compilation The assets object of compilation can be used for writing new files. You can also capture already created assets, manipulate them, and write them back. To write an asset, you have to use webpack-sources file abstraction. Install it first: npm install webpack-sources --save-dev

Adjust the code as follows to write through RawSource : plugins/demo-plugin.js

const { RawSource } = require("webpack-sources"); module.exports = class DemoPlugin { constructor(options) { this.options = options; } apply(compiler) { const { name } = this.options; compiler.plugin("emit", (compilation, cb) => { console.log(compilation); compilation.assets[name] = new RawSource("demo"); cb(); }); } };

After building, you should see output: Hash: d698e1dab6472ba42525 Version: webpack 3.8.1 Time: 51ms Asset Size Chunks Chunk Names lib.js 2.9 kB 0 [emitted] lib demo 4 bytes [emitted] [0] ./app/shake.js 107 bytes {0} [built]

If you examine build/demo file, you'll see it contains the word demo as per code above.

Compilation has a set of hooks of its own as covered in the official compilation reference.

Managing Warnings and Errors Plugin execution can be caused to fail by throwing ( throw new Error("Message") ). If you validate options, you can use this method. In case you want to give the user a warning or an error message during compilation, you should use compilation.warnings and compilation.errors . Example: compilation.warnings.push("warning"); compilation.errors.push("error");

There is no way pass information messages to webpack yet although there is a logging proposal. If you want to use console.log for this purpose, push it behind a verbose flag. The problem is that console.log will print to stdout and it will end up in webpack's --json output as a result. A flag will allow the user to work around this problem.

Plugins Can Have Plugins A plugin can provide hooks of its own. html-webpack-plugin uses plugins to extend itself as discussed in the Getting Started chapter.

Plugins Can Run Compilers of Their Own In special cases, like offline-plugin, it makes sense to run a child compiler. It gives full control over related entries and output. Arthur Stolyar, the author of the plugin, has explained the idea of child compilers at Stack Overflow.

Conclusion When you begin to design a plugin, spend time studying existing plugins that are close enough. Develop plugins piece-wise so that you validate one piece at a time. Studying webpack source can give more insight given it's a collection of plugins itself. To recap: Plugins can intercept webpack's execution and extend it making them more flexible than loaders. Plugins can be combined with loaders. ExtractTextPlugin works this way. The accompanying loader is used to mark assets to extract. Plugins have access to webpack's compiler and compilation processes. Both provide hooks for different stages of webpack's execution flow and allow you to manipulate it. Webpack itself works this way. Plugins can emit new assets and shape existing assets. Plugins can implement plugin systems of their own. HtmlWebpackPlugin is an example of such plugin. Plugins can run compilers on their own. The isolation gives more control and allows plugins like offline-plugin to be written.

Subscribe to the blog updates If you enjoyed this page, consider subscribing to the mailing list below or following @survivejs for occasional updates. There is also RSS available for old beards (no pun intended).

SUBSCRIBE

EMAIL

Previous chapter

Next chapter

← Extending with Loaders

Conclusion Õ

This book is available through Leanpub (digital), Amazon (paperback), and Kindle (digital). By purchasing the book you support the development of further content. A part of profit (~30%) goes to Tobias Koppers, the author of webpack.

@survivejs

Mailing List

Gitter Chat

GitHub

Presentations

Contact

Ask Me Anything

RSS

From the Blog lint-staged - Run Linters on git Staged Files - Interview with Andrey Okonetchnikov "SurviveJS - Webpack" Updated to webpack 4 Webpack in Munich, May 2018 Experiences on Concat 2018 Verdaccio - A lightweight npm proxy registry - Interview with Juan Picado Parket - A state management library inspired by mobx-state-tree - Interview with Leah Ullmann substyle - Build Styling Agnostic Components for React - Interview with Jan-Felix Schwarz

BUY AT LEANPUB

BUY AT LEANPUB

BUY AT LEANPUB BUY AT AMAZON BUY FOR KINDLE

N EED H EL P?

Smile Life

When life gives you a hundred reasons to cry, show life that you have a thousand reasons to smile

Get in touch

© Copyright 2015 - 2024 PDFFOX.COM - All rights reserved.