mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
web worker example
This commit is contained in:
parent
56bcd609fd
commit
cd9a6c2c05
21
examples/web-worker/.eslintrc.js
Normal file
21
examples/web-worker/.eslintrc.js
Normal file
@ -0,0 +1,21 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
},
|
||||
extends: [
|
||||
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
|
||||
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
|
||||
'plugin:vue/strongly-recommended'
|
||||
],
|
||||
// required to lint *.vue files
|
||||
plugins: [
|
||||
'vue'
|
||||
],
|
||||
// add your custom rules here
|
||||
rules: {}
|
||||
}
|
11
examples/web-worker/.gitignore
vendored
Normal file
11
examples/web-worker/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# logs
|
||||
npm-debug.log
|
||||
|
||||
# Nuxt build
|
||||
.nuxt
|
||||
|
||||
# Nuxt generate
|
||||
dist
|
26
examples/web-worker/README.md
Normal file
26
examples/web-worker/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# web-worker
|
||||
|
||||
> Nuxt.js project
|
||||
|
||||
In nuxt 1.4 and below you have to create a production build to use web workers.
|
||||
|
||||
## Build Setup
|
||||
|
||||
``` bash
|
||||
# install dependencies
|
||||
$ npm install # Or yarn install
|
||||
|
||||
# serve with hot reload at localhost:3000
|
||||
# nuxt 1.4 and below does not support web workers in dev mode
|
||||
$ npm run dev
|
||||
|
||||
# build for production and launch server
|
||||
# in nuxt 1.4 and below you have to create a production build to use web workers
|
||||
$ npm run build
|
||||
$ npm start
|
||||
|
||||
# generate static project
|
||||
$ npm run generate
|
||||
```
|
||||
|
||||
For detailed explanation on how things work, checkout the [Nuxt.js docs](https://github.com/nuxt/nuxt.js).
|
8
examples/web-worker/assets/README.md
Normal file
8
examples/web-worker/assets/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# ASSETS
|
||||
|
||||
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
|
||||
|
||||
More information about the usage of this directory in the documentation:
|
||||
https://nuxtjs.org/guide/assets#webpacked
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
17
examples/web-worker/assets/js/Example.worker.js
Normal file
17
examples/web-worker/assets/js/Example.worker.js
Normal file
@ -0,0 +1,17 @@
|
||||
// // block for `time` ms, then return the number of loops we could run in that time:
|
||||
function expensive(time) {
|
||||
let start = Date.now(),
|
||||
count = 0
|
||||
while (Date.now() - start < time) count++
|
||||
return count
|
||||
}
|
||||
|
||||
// Respond to message from parent thread
|
||||
self.addEventListener('message', (event) => {
|
||||
console.log('worker', event.data)
|
||||
|
||||
if (event.data.action === 'expensive' && event.data.time) {
|
||||
// Post data to parent thread
|
||||
self.postMessage(expensive(Number(event.data.time)))
|
||||
}
|
||||
})
|
79
examples/web-worker/components/AppLogo.vue
Normal file
79
examples/web-worker/components/AppLogo.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="VueToNuxtLogo">
|
||||
<div class="Triangle Triangle--two"/>
|
||||
<div class="Triangle Triangle--one"/>
|
||||
<div class="Triangle Triangle--three"/>
|
||||
<div class="Triangle Triangle--four"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.VueToNuxtLogo {
|
||||
display: inline-block;
|
||||
animation: turn 2s linear forwards 1s;
|
||||
transform: rotateX(180deg);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 180px;
|
||||
width: 245px;
|
||||
}
|
||||
|
||||
.Triangle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.Triangle--one {
|
||||
border-left: 105px solid transparent;
|
||||
border-right: 105px solid transparent;
|
||||
border-bottom: 180px solid #41B883;
|
||||
}
|
||||
|
||||
.Triangle--two {
|
||||
top: 30px;
|
||||
left: 35px;
|
||||
animation: goright 0.5s linear forwards 3.5s;
|
||||
border-left: 87.5px solid transparent;
|
||||
border-right: 87.5px solid transparent;
|
||||
border-bottom: 150px solid #3B8070;
|
||||
}
|
||||
|
||||
.Triangle--three {
|
||||
top: 60px;
|
||||
left: 35px;
|
||||
animation: goright 0.5s linear forwards 3.5s;
|
||||
border-left: 70px solid transparent;
|
||||
border-right: 70px solid transparent;
|
||||
border-bottom: 120px solid #35495E;
|
||||
}
|
||||
|
||||
.Triangle--four {
|
||||
top: 120px;
|
||||
left: 70px;
|
||||
animation: godown 0.5s linear forwards 3s;
|
||||
border-left: 35px solid transparent;
|
||||
border-right: 35px solid transparent;
|
||||
border-bottom: 60px solid #fff;
|
||||
}
|
||||
|
||||
@keyframes turn {
|
||||
100% {
|
||||
transform: rotateX(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes godown {
|
||||
100% {
|
||||
top: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes goright {
|
||||
100% {
|
||||
left: 70px;
|
||||
}
|
||||
}
|
||||
</style>
|
6
examples/web-worker/components/README.md
Normal file
6
examples/web-worker/components/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# COMPONENTS
|
||||
|
||||
The components directory contains your Vue.js Components.
|
||||
Nuxt.js doesn't supercharge these components.
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
8
examples/web-worker/layouts/README.md
Normal file
8
examples/web-worker/layouts/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# LAYOUTS
|
||||
|
||||
This directory contains your Application Layouts.
|
||||
|
||||
More information about the usage of this directory in the documentation:
|
||||
https://nuxtjs.org/guide/views#layouts
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
58
examples/web-worker/layouts/default.vue
Normal file
58
examples/web-worker/layouts/default.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div>
|
||||
<nuxt/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
html {
|
||||
font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
word-spacing: 1px;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*, *:before, *:after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-left: 15px;
|
||||
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.button--green {
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #3b8070;
|
||||
color: #3b8070;
|
||||
text-decoration: none;
|
||||
padding: 10px 30px;
|
||||
}
|
||||
|
||||
.button--green:hover {
|
||||
color: #fff;
|
||||
background-color: #3b8070;
|
||||
}
|
||||
|
||||
.button--grey {
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #35495e;
|
||||
color: #35495e;
|
||||
text-decoration: none;
|
||||
padding: 10px 30px;
|
||||
}
|
||||
|
||||
.button--grey:hover {
|
||||
color: #fff;
|
||||
background-color: #35495e;
|
||||
}
|
||||
</style>
|
49
examples/web-worker/nuxt.config.js
Normal file
49
examples/web-worker/nuxt.config.js
Normal file
@ -0,0 +1,49 @@
|
||||
module.exports = {
|
||||
/*
|
||||
** Headers of the page
|
||||
*/
|
||||
head: {
|
||||
title: 'web-worker',
|
||||
meta: [
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
{ hid: 'description', name: 'description', content: 'Nuxt.js project' }
|
||||
],
|
||||
link: [
|
||||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
|
||||
]
|
||||
},
|
||||
/*
|
||||
** Customize the progress bar color
|
||||
*/
|
||||
loading: { color: '#3B8070' },
|
||||
plugins: [
|
||||
{ src: '~/plugins/inject-ww', ssr: false } // web workers are only available client-side, hence ssr: false
|
||||
],
|
||||
/*
|
||||
** Build configuration
|
||||
*/
|
||||
build: {
|
||||
/*
|
||||
** Run ESLint on save
|
||||
*/
|
||||
extend (config, { isDev, isClient }) {
|
||||
if (isDev && isClient) {
|
||||
config.module.rules.push({
|
||||
enforce: 'pre',
|
||||
test: /\.(js|vue)$/,
|
||||
loader: 'eslint-loader',
|
||||
exclude: /(node_modules)/
|
||||
})
|
||||
}
|
||||
|
||||
if (isClient) { // web workers are only available client-side
|
||||
config.module.rules.push({
|
||||
test: /\.worker\.js$/, // this will pick up all .js files that ends with ".worker.js"
|
||||
loader: 'worker-loader',
|
||||
exclude: /(node_modules)/
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
examples/web-worker/package.json
Normal file
21
examples/web-worker/package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "web-worker",
|
||||
"description": "Demo web workers in nuxt.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate",
|
||||
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
|
||||
"precommit": "npm run lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint": "^4.19.0",
|
||||
"nuxt": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-plugin-vue": "^4.3.0",
|
||||
"worker-loader": "^1.1.1"
|
||||
}
|
||||
}
|
7
examples/web-worker/pages/README.md
Normal file
7
examples/web-worker/pages/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# PAGES
|
||||
|
||||
This directory contains your Application Views and Routes.
|
||||
The framework reads all the .vue files inside this directory and creates the router of your application.
|
||||
|
||||
More information about the usage of this directory in the documentation:
|
||||
https://nuxtjs.org/guide/routing
|
160
examples/web-worker/pages/index.vue
Normal file
160
examples/web-worker/pages/index.vue
Normal file
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<section class="container">
|
||||
<div>
|
||||
<app-logo/>
|
||||
<h1 class="title">
|
||||
web-worker
|
||||
</h1>
|
||||
<h2 class="subtitle">
|
||||
Nuxt.js project
|
||||
</h2>
|
||||
<p>{{ notification }}</p>
|
||||
<ul class="list">
|
||||
<li>Number of Web Workers: {{ workers.length }}</li>
|
||||
<li>Number of long Running Workers: {{ longRunningWorkers.length }}</li>
|
||||
<li>Number of unused Workers: {{ workers.filter(w => !w.inUse).length }}</li>
|
||||
</ul>
|
||||
<div class="links">
|
||||
<a
|
||||
:class="needWorkerSetup ? 'hidden' : 'visible'"
|
||||
@click="test"
|
||||
class="button button--green">Test Worker</a>
|
||||
<a
|
||||
:class="needWorkerSetup ? 'hidden' : 'visible'"
|
||||
@click="long(4000)"
|
||||
class="button button--green">Execute long running Worker</a>
|
||||
<a
|
||||
:class="needWorkerSetup || !longRunningWorkers.length ? 'hidden' : 'visible'"
|
||||
@click="freeWorker"
|
||||
class="button button--green">Free long running Worker</a>
|
||||
<a
|
||||
@click="removeWorker"
|
||||
class="button button--grey">Remove Web Worker</a>
|
||||
<a
|
||||
@click="createWorkers"
|
||||
class="button button--grey">Create more Workers</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppLogo from '~/components/AppLogo.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AppLogo
|
||||
},
|
||||
computed: {
|
||||
needWorkerSetup () {
|
||||
return this.workers.length === 0 && this.longRunningWorkers.length === 0
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
notification: '',
|
||||
workers: [],
|
||||
workerIndex: 0,
|
||||
longRunningWorkers: [],
|
||||
longIndex: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
workers (workers) {
|
||||
if (workers.length === 0) this.notification = 'Zero free Web Workers - click "Create more Workers"'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
test () {
|
||||
const worker = this.workers[this.workerIndex++ % this.workers.length]
|
||||
|
||||
if (worker) worker.postMessage({ hello: 'world' })
|
||||
else this.notification = 'No more test workers available'
|
||||
},
|
||||
long (miliseconds) {
|
||||
let worker = this.workers.shift()
|
||||
|
||||
if (worker) {
|
||||
worker.onmessage = (event) => {
|
||||
console.log(`expensive made ${event.data} loops`)
|
||||
}
|
||||
this.longRunningWorkers.push(worker)
|
||||
} else {
|
||||
worker = this.longRunningWorkers[ this.longIndex++ % this.longRunningWorkers.length]
|
||||
}
|
||||
|
||||
worker.postMessage({ action: 'expensive', time: miliseconds })
|
||||
},
|
||||
freeWorker () {
|
||||
const worker = this.longRunningWorkers.pop()
|
||||
worker.onmessage = null
|
||||
this.workers.push(worker)
|
||||
this.notification = 'Worker freed'
|
||||
},
|
||||
removeWorker () {
|
||||
const worker = this.workers.pop() || this.longRunningWorkers.pop()
|
||||
|
||||
if (!worker) return
|
||||
|
||||
if (this.longRunningWorkers.indexOf(worker) > -1) this.longRunningWorkers.splice(this.longRunningWorkers.indexOf(worker), 1)
|
||||
|
||||
worker.onmessage = null
|
||||
worker.terminate()
|
||||
},
|
||||
createWorkers () {
|
||||
if (process.browser) {
|
||||
for(let i = 0, len = navigator.hardwareConcurrency || 1; i < len; i++) {
|
||||
this.workers.push(this.$worker.createWorker())
|
||||
}
|
||||
|
||||
this.notification = 'Go nuts!'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
|
||||
display: block;
|
||||
font-weight: 300;
|
||||
font-size: 100px;
|
||||
color: #35495e;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-weight: 300;
|
||||
font-size: 42px;
|
||||
color: #526488;
|
||||
word-spacing: 5px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.links {
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.list {
|
||||
text-align: left;
|
||||
color: #526488;
|
||||
list-style: none;
|
||||
}
|
||||
</style>
|
8
examples/web-worker/plugins/README.md
Normal file
8
examples/web-worker/plugins/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# PLUGINS
|
||||
|
||||
This directory contains your Javascript plugins that you want to run before instantiating the root vue.js application.
|
||||
|
||||
More information about the usage of this directory in the documentation:
|
||||
https://nuxtjs.org/guide/plugins
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
9
examples/web-worker/plugins/inject-ww.js
Normal file
9
examples/web-worker/plugins/inject-ww.js
Normal file
@ -0,0 +1,9 @@
|
||||
import ExampleWorker from '~/assets/js/Example.worker.js' // worker files has to end in ".worker.js" - see nuxt.config.js
|
||||
|
||||
export default (context, inject) => {
|
||||
inject('worker', {
|
||||
createWorker () {
|
||||
return new ExampleWorker()
|
||||
}
|
||||
})
|
||||
}
|
11
examples/web-worker/static/README.md
Normal file
11
examples/web-worker/static/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# STATIC
|
||||
|
||||
This directory contains your static files.
|
||||
Each file inside this directory is mapped to /.
|
||||
|
||||
Example: /static/robots.txt is mapped as /robots.txt.
|
||||
|
||||
More information about the usage of this directory in the documentation:
|
||||
https://nuxtjs.org/guide/assets#static
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
BIN
examples/web-worker/static/favicon.ico
Normal file
BIN
examples/web-worker/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in New Issue
Block a user