Skip to content

Commit d3d5f85

Browse files
committed
Merge branch 'release/1.1.0'
2 parents 2ed49cc + ed0b601 commit d3d5f85

13 files changed

+351
-75
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
5+
---
6+
7+
**Describe the bug**
8+
A clear and concise description of what the bug is.
9+
10+
**To Reproduce**
11+
Steps to reproduce the behavior:
12+
1. Go to '...'
13+
2. Click on '....'
14+
3. Scroll down to '....'
15+
4. See error
16+
17+
**Expected behavior**
18+
A clear and concise description of what you expected to happen.
19+
20+
**Screenshots**
21+
If applicable, add screenshots to help explain your problem.
22+
23+
**Additional context**
24+
Package version: X.X.X
25+
Vue version: X.X.X
26+
Vue CLI version: X.X.X
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
5+
---
6+
7+
**Is your feature request related to a problem? Please describe.**
8+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9+
10+
**Describe the solution you'd like**
11+
A clear and concise description of what you want to happen.
12+
13+
**Describe alternatives you've considered**
14+
A clear and concise description of any alternative solutions or features you've considered.
15+
16+
**Additional context**
17+
Add any other context or screenshots about the feature request here.

.prettierrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"printWidth": 120
3+
}

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"editor.rulers": [120]
3+
}

CODE_OF_CONDUCT.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
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.
6+
7+
## Our Standards
8+
9+
Examples of behavior that contributes to creating a positive environment include:
10+
11+
* Using welcoming and inclusive language
12+
* Being respectful of differing viewpoints and experiences
13+
* Gracefully accepting constructive criticism
14+
* Focusing on what is best for the community
15+
* Showing empathy towards other community members
16+
17+
Examples of unacceptable behavior by participants include:
18+
19+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
20+
* Trolling, insulting/derogatory comments, and personal or political attacks
21+
* Public or private harassment
22+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
23+
* Other conduct which could reasonably be considered inappropriate in a professional setting
24+
25+
## Our Responsibilities
26+
27+
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.
28+
29+
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.
30+
31+
## Scope
32+
33+
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.
34+
35+
## Enforcement
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at solarliner@gmail.com. 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.
38+
39+
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.
40+
41+
## Attribution
42+
43+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44+
45+
[homepage]: http://contributor-covenant.org
46+
[version]: http://contributor-covenant.org/version/1/4/

CONTRIBUTING.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Contributing guidelines
2+
3+
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.
4+
5+
## Pull Requests specifics
6+
7+
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.

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Nathan Graule
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

PULL_REQUEST_TEMPLATE.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!-- First open an issue in order to engage the author and the community - then work on your PR. -->
2+
3+
**What**:
4+
5+
**Why**:
6+
7+
**How**:
8+
9+
- [ ] I am working based off of `develop`
10+
- [ ] I have rebased my PR off of `develop`

README.md

+80-15
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

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

5+
**Looking for a co-maintainer**: I'm continuing to maintain this project, hoever
6+
I still would like help on some of the issues, and generally to help me keep this
7+
plugin going as it's getting more and more popular. If you think you can help,
8+
file and issue for maintainship!
9+
10+
**Support requests**: Vue has a Discord server and I often lurk in there. And
11+
while there is a support label in the Issues, GitHub isn't the place for support
12+
requests and should be directed to me in the
13+
[Vue Land Discord server](https://vue-land.js.org).
14+
515
## Install
616

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

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

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

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

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

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

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

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

132+
### User post processing function
133+
134+
Pupeteer allows to postprocess the HTML after it's been snapshot, and the plugin
135+
allows you to provide your own function if you need to.
136+
137+
Add a `postProcess` option into your `vue.config.js` file to provide a custom
138+
post-processing function to run on every build.
139+
122140
Exemple configuration:
123141

124-
```json
125-
{
126-
"renderRoutes": ["/", "/about"],
127-
"useRenderEvent": true,
128-
"headless": true,
129-
"onlyProduction": true,
130-
"customRendererConfig": {
131-
"renderAfterDocumentEvent": "my-custom-event"
142+
```js
143+
// vue.config.js
144+
145+
module.exports = {
146+
pluginOptions: {
147+
prerenderSpa: {
148+
registry: undefined,
149+
renderRoutes: [
150+
'/',
151+
'/about'
152+
],
153+
useRenderEvent: true,
154+
headless: true,
155+
onlyProduction: true,
156+
postProcess: route => {
157+
// Defer scripts and tell Vue it's been server rendered to trigger hydration
158+
route.html = route.html
159+
.replace(/<script (.*?)>/g, '<script $1 defer>')
160+
.replace('id="app"', 'id="app" data-server-rendered="true"');
161+
return route;
162+
}
163+
}
132164
}
133165
}
134166
```
@@ -146,14 +178,47 @@ throughput.
146178

147179
## Notices
148180

181+
### Backend routing configuration for deployments
182+
183+
Since the `index.html` is now (most likely, depending on your list of routes)
184+
pre-rendered, pointing to it from another path will lead to whiteflashing as
185+
the pre-rendered content (of the index page) will not match the expected
186+
content of the route (say from an about page). For this reason, the plugin
187+
outputs another file called `app.html` that doesn't get pre-rendered. **For
188+
better user experience, it is recommended to route non-prerendered routes to
189+
this file** instead of the default `index.html`.
190+
191+
Here's an example nginx configuration snippet:
192+
193+
```nginx
194+
location / {
195+
try_files $url $url/index.html $url.html /app.html
196+
}
197+
```
198+
199+
And an example Firebase configuration (taken from https://stackoverflow.com/a/51218261):
200+
201+
```json
202+
"rewrites": [
203+
{
204+
"source": "**",
205+
"destination": "/app.html"
206+
},
207+
{
208+
"source": "/",
209+
"destination": "/index.html"
210+
}
211+
]
212+
```
213+
149214
### CI/CD workflows
150215

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

158223
### Compatibility with other Vue CLI plugins
159224

generator/index.js

+13-15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
module.exports = (api, options) => {
2-
api.extendPackage({
3-
devDependencies: {
4-
"prerender-spa-plugin": "^3.2.1"
5-
}
6-
});
7-
82
api.onCreateComplete(() => {
93
const fs = require("fs");
10-
const configPath = api.resolve("./.prerender-spa.json");
11-
fs.writeFileSync(configPath, JSON.stringify(options), {
12-
encoding: "utf-8"
13-
});
144

155
if (options.useRenderEvent) {
166
const ext = api.hasPlugin("typescript") ? "ts" : "js";
@@ -20,15 +10,23 @@ module.exports = (api, options) => {
2010
.readFileSync(mainPath, { encoding: "utf-8" })
2111
.split(/\r?\n/g)
2212
.reverse();
23-
const vueRenderIndex = mainFileLines.findIndex(line =>
24-
line.match(/render\:/)
25-
);
26-
if (!mainFileLines[vueRenderIndex].endsWith(","))
27-
mainFileLines[vueRenderIndex] += ",";
13+
const vueRenderIndex = mainFileLines.findIndex(line => line.match(/render\:/));
14+
if (!mainFileLines[vueRenderIndex].endsWith(",")) mainFileLines[vueRenderIndex] += ",";
2815
mainFileLines[vueRenderIndex] += '\n mounted: () => document.dispatchEvent(new Event("x-app-rendered")),';
2916
fs.writeFileSync(mainPath, mainFileLines.reverse().join("\n"), {
3017
encoding: "utf-8"
3118
});
3219
}
3320
});
21+
22+
api.extendPackage({
23+
devDependencies: {
24+
"prerender-spa-plugin": "^3.2.1"
25+
},
26+
vue: {
27+
pluginOptions: {
28+
prerenderSpa: options
29+
}
30+
}
31+
});
3432
};

0 commit comments

Comments
 (0)