Skip to content

Commit

Permalink
Merge branch 'release/1.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
SolarLiner committed Jan 2, 2019
2 parents 2ed49cc + ed0b601 commit d3d5f85
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 75 deletions.
26 changes: 26 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: Bug report
about: Create a report to help us improve

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Package version: X.X.X
Vue version: X.X.X
Vue CLI version: X.X.X
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"printWidth": 120
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.rulers": [120]
}
46 changes: 46 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [email protected]. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Contributing guidelines

You are very welcome to contribute. In most cases a template will be provided to you when opening an issue or a PR; please follow it as strictly as possible in order to maximize information throughput.

## Pull Requests specifics

Before submitting a pull request, it is preferable and strongly recommended to first open an issue, in order to discuss broadly on the implementation; the specifics can be put into the actual PR, where and when code will be reviewed.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Nathan Graule

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
10 changes: 10 additions & 0 deletions PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- First open an issue in order to engage the author and the community - then work on your PR. -->

**What**:

**Why**:

**How**:

- [ ] I am working based off of `develop`
- [ ] I have rebased my PR off of `develop`
95 changes: 80 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

Add `prerender-spa-plugin` into your Vue application with zero configuration.

**Looking for a co-maintainer**: I'm continuing to maintain this project, hoever
I still would like help on some of the issues, and generally to help me keep this
plugin going as it's getting more and more popular. If you think you can help,
file and issue for maintainship!

**Support requests**: Vue has a Discord server and I often lurk in there. And
while there is a support label in the Issues, GitHub isn't the place for support
requests and should be directed to me in the
[Vue Land Discord server](https://vue-land.js.org).

## Install

Add prerendering to your Vue application with:
Expand All @@ -16,7 +26,7 @@ You'll be asked a few questions, detailed below, to which the default answers
are the most common options.

The main option to fit to your needs is the **list of routes to pre-render**.
Speccify them as a comma-separated list:
Specify them as a comma-separated list:

```bash
? Which routes to pre-render? (list them separated by a comma) /,/about,/contact
Expand All @@ -35,9 +45,9 @@ rendered, which should cover most SPAs. If your project uses vue-router, you
can specify a list of routes that do not depend on dynamic content (like user
uploaded data, public profiles, etc.). For example you can add your about page
as well as a contact page - those will load faster, and will be indexed by bots
who do not execute JavaScript, improving Search Engines rankigs.
who do not execute JavaScript, improving Search Engines rankings.

Note that if you want to also pre-render user generated content, you *will*
Note that if you want to also pre-render user generated content, you _will_
have to switch to Server-Side Rendering, there are no other options.

#### What it does to your project
Expand All @@ -62,7 +72,7 @@ realizing what's happening.

When enabling the event-based snapshot trigger, it will tell
`PrerenderSPAPlugin` to listen for an `x-app-rendered` event. Your main file
is then modified to add a `mounted()` hook where the even will fire. Note that
is then modified to add a `mounted()` hook where the event will fire. Note that
it doesn't check if the hook is already present, nor does it parses the file;
it just looks for the line starting with `render:` (minus whitespaces) and
inserts the `mounted()` hook below. If you already have the hook set up, or if
Expand Down Expand Up @@ -108,7 +118,7 @@ that option.
This option is configured from within the Vue CLI itself, but serves to a whole
host of plugins to determine whether to turn on parallel jobs / multi-threading.

This plugin uses it to tell `prerender-spa-plugin` to render pages concurently
This plugin uses it to tell `prerender-spa-plugin` to render pages concurrently
(meaning in parallel) or not by setting the `maxConcurrentRoutes` parameter to
either 1 or 4, if the build is respectively single-threaded or multi-threaded.

Expand All @@ -119,16 +129,38 @@ root directory of the project; where you can specify custom options for the
Puppeteer renderer. It will be merged, and its options will overwrite those set
by the plugin itself.

### User post processing function

Pupeteer allows to postprocess the HTML after it's been snapshot, and the plugin
allows you to provide your own function if you need to.

Add a `postProcess` option into your `vue.config.js` file to provide a custom
post-processing function to run on every build.

Exemple configuration:

```json
{
"renderRoutes": ["/", "/about"],
"useRenderEvent": true,
"headless": true,
"onlyProduction": true,
"customRendererConfig": {
"renderAfterDocumentEvent": "my-custom-event"
```js
// vue.config.js

module.exports = {
pluginOptions: {
prerenderSpa: {
registry: undefined,
renderRoutes: [
'/',
'/about'
],
useRenderEvent: true,
headless: true,
onlyProduction: true,
postProcess: route => {
// Defer scripts and tell Vue it's been server rendered to trigger hydration
route.html = route.html
.replace(/<script (.*?)>/g, '<script $1 defer>')
.replace('id="app"', 'id="app" data-server-rendered="true"');
return route;
}
}
}
}
```
Expand All @@ -146,14 +178,47 @@ throughput.

## Notices

### Backend routing configuration for deployments

Since the `index.html` is now (most likely, depending on your list of routes)
pre-rendered, pointing to it from another path will lead to whiteflashing as
the pre-rendered content (of the index page) will not match the expected
content of the route (say from an about page). For this reason, the plugin
outputs another file called `app.html` that doesn't get pre-rendered. **For
better user experience, it is recommended to route non-prerendered routes to
this file** instead of the default `index.html`.

Here's an example nginx configuration snippet:

```nginx
location / {
try_files $url $url/index.html $url.html /app.html
}
```

And an example Firebase configuration (taken from https://stackoverflow.com/a/51218261):

```json
"rewrites": [
{
"source": "**",
"destination": "/app.html"
},
{
"source": "/",
"destination": "/index.html"
}
]
```

### CI/CD workflows

Because the `prerender-spa-plugin` uses a headless Chrome instance, your
regular `node:latest` Docker image will not chug your build correctly; you need
system dependencies and configuration that might not be efficient to add to the
job itself - rather, it is recommended to switch to a Node.js + Puppetteer
job itself - rather, it is recommended to switch to a Node.js + Puppeteer
image where you can just use your `install && build` workflow without any
additional configuration. I personally use the `alekzonder/puppeteer` image.
additional configuration. I personally use the `alekzonder/puppeteer` image.

### Compatibility with other Vue CLI plugins

Expand Down
28 changes: 13 additions & 15 deletions generator/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
module.exports = (api, options) => {
api.extendPackage({
devDependencies: {
"prerender-spa-plugin": "^3.2.1"
}
});

api.onCreateComplete(() => {
const fs = require("fs");
const configPath = api.resolve("./.prerender-spa.json");
fs.writeFileSync(configPath, JSON.stringify(options), {
encoding: "utf-8"
});

if (options.useRenderEvent) {
const ext = api.hasPlugin("typescript") ? "ts" : "js";
Expand All @@ -20,15 +10,23 @@ module.exports = (api, options) => {
.readFileSync(mainPath, { encoding: "utf-8" })
.split(/\r?\n/g)
.reverse();
const vueRenderIndex = mainFileLines.findIndex(line =>
line.match(/render\:/)
);
if (!mainFileLines[vueRenderIndex].endsWith(","))
mainFileLines[vueRenderIndex] += ",";
const vueRenderIndex = mainFileLines.findIndex(line => line.match(/render\:/));
if (!mainFileLines[vueRenderIndex].endsWith(",")) mainFileLines[vueRenderIndex] += ",";
mainFileLines[vueRenderIndex] += '\n mounted: () => document.dispatchEvent(new Event("x-app-rendered")),';
fs.writeFileSync(mainPath, mainFileLines.reverse().join("\n"), {
encoding: "utf-8"
});
}
});

api.extendPackage({
devDependencies: {
"prerender-spa-plugin": "^3.2.1"
},
vue: {
pluginOptions: {
prerenderSpa: options
}
}
});
};
Loading

0 comments on commit d3d5f85

Please sign in to comment.