Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/line/grow-loader
A webpack loader to split class methods by decorators
https://github.com/line/grow-loader
javascript loader webpack
Last synced: about 1 month ago
JSON representation
A webpack loader to split class methods by decorators
- Host: GitHub
- URL: https://github.com/line/grow-loader
- Owner: line
- License: apache-2.0
- Archived: true
- Created: 2017-11-28T03:54:10.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-11-01T16:33:45.000Z (about 5 years ago)
- Last Synced: 2024-05-14T00:34:33.945Z (8 months ago)
- Topics: javascript, loader, webpack
- Language: JavaScript
- Homepage:
- Size: 211 KB
- Stars: 89
- Watchers: 42
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# grow-loader
[![Travis CI](https://travis-ci.org/line/grow-loader.svg?branch=master)](https://travis-ci.org/line/grow-loader) [![npm version](https://badge.fury.io/js/grow-loader.svg)](https://badge.fury.io/js/grow-loader)
The `grow-loader` is a webpack loader to let you split "growable" methods into separate files, by simply adding a decorator to the methods in class declarations.
By "growable methods", we mean the methods that need to be dynamically imported. To learn more about dynamic import, read [this document](https://webpack.js.org/guides/code-splitting/#dynamic-imports) from webpack.
Learn more about grow-loader:
- [Installing grow-loader](#installing-grow-loader)
- [Using grow-loader](#using-grow-loader)
- [Background story](#background-story)
- [Contributing](#Contributing)
- [License](#License)## Installing grow-loader
To install grow-loader, run the following command on your terminal.```
npm install --save-dev "grow-loader"
```## Using grow-loader
- [Getting started](#getting-started)
- [Customizing loader options](#customizing-loader-options)### Getting started
1. In your webpack config, add `grow-loader` _before_ the `babel-loader`.> Note. Webpack chains loaders from right to left, so to run a loader before another loader, it should be put latter. See https://webpack.js.org/configuration/module/#rule-use for more information.
**webpack.config.js**
```js
{
test: /\.jsx?$/,
use: [
'babel-loader',
'grow-loader'
]
}
```2. Add the `@grow` decorator to your class methods that need to "grow". The functions marked will be split into separate files.
```js
class SampleClass {@grow
methodToGrow() {
// ...
}@grow
methodToGrowAndBind = () => {
// ...
}methodToBeBundled(){
}
}
```If you use any linter tool before grow-loader, you may use the following import statement (which does nothing) to avoid syntax error.
```js
import grow from 'grow-loader/lib/grow';
```3. To install split functions back, call the `grow()` function.
```js
const sample = new SampleClass();
console.assert(a.methodToGrow === undefined);
console.assert(a.methodToGrowAndBind === undefined);sample.grow().then(() => {
sample.methodToGrow();
sample.methodToGrowAndBind();
});
```### Customizing loader options
To avoid naming conflicts, you can customize the following grow-loader options.
| Option | Default Value | Description |
| -------|---------|-------------|
| methodName | `grow` | The name of the method to be called before a split method. e.g. `grow()` |
| decoratorName | `grow` | The decorator to be detected. e.g. `@grow`. |The grow-loader options are to be defined in your webpack config or in an `import` statement.
> Note. Learn more about configuring loaders from the [webpack documentation on loaders](https://webpack.js.org/concepts/loaders/).
The following is an example of customizing the grow method as `myGrow()` and the decorator as `@myGrowDec`.
```js
{
test: /\.jsx?$/,
use: [
'babel-loader',
'grow-loader?methodName=myGrow&decoratorName=myGrowDec'
]
}
```## React Component Example
Using grow-loader to code-split requires only a few modifications to your code. Here is an example:**Before applying grow-loader**
```js
export default class A extends React.Component {methodToGrow(){}
anotherMethodToGrow(){}
methodToBeBundled(){}
render(){
return...
}
}
```**After applying grow-loader**
```js
class GrowablePage extends React.Component {
componentDidMount() {
if (this.grow) {
this.grow().then(() => {
this.hasGrown = true;
this.forceUpdate();
});
}
}
}export default class A extends GrowablePage {
@grow
methodToGrow(){ }@grow
anotherMethodToGrow(){ }methodToBeBundled{ }
@grow
renderMore() {
return...
}render(){
return
{ this.hasGrown ? this.renderMore() : null }
}
}
```## Background story
Higher-Order Components(HOC) is a common solution in implementing code-splitting. But we found HOC solutions unsuitable for our project built with React.js.- We use different placeholder components for almost every page, but HOC solutions only support a common component for all pages.
- Instant page transition was our ultimate goal, but the following two problems had surfaced in using HOC solutions:
- We organize pages in a stack—[see our blog posting on this](https://engineering.linecorp.com/en/blog/detail/235)—the hooks provided could not be easily integrated.
- A lot of code modifications were required. Preloading pages would help our case, but preloading costs a lot in time and management. And page transition still felt janky for long pages because of DOM manipulation.That's why we decided to split every page into two parts:
- **Basic part**: Contains placeholder components in the first view, which are to be included in the main bundle.
- **Grown part**: Parts to be dynamically imported, and rendered after the **Basic Part**But manually splitting files requires a heavy workload and makes methods in both parts messy. This is why we created the `grow-loader` to do it in a flexible way.
## Contributing
Please check [CONTRIBUTING](./CONTRIBUTING.md) before making a contribution.
## License
[Apache License Version 2.0](./LICENSE)