fix(client): prevent endless SASS conversion
This commit is contained in:
5
client/.gitignore
vendored
5
client/.gitignore
vendored
@ -9,6 +9,5 @@ config/env.json
|
|||||||
/public
|
/public
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
./static/js/frame-runner.js
|
/static/js
|
||||||
./static/js/frame-runner.js.map
|
./static/_redirects
|
||||||
./static/_redirects
|
|
||||||
|
11
client/src/client/workers/sass.js
Normal file
11
client/src/client/workers/sass.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
importScripts(
|
||||||
|
'https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.10.11/sass.sync.min.js'
|
||||||
|
);
|
||||||
|
|
||||||
|
onmessage = e => {
|
||||||
|
const data = e.data;
|
||||||
|
Sass.compile(data, result => {
|
||||||
|
self.postMessage(result.text);
|
||||||
|
});
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
import favicons from './favicons';
|
import favicons from './favicons';
|
||||||
import meta from './meta';
|
import meta from './meta';
|
||||||
import mathjax from './mathjax';
|
import mathjax from './mathjax';
|
||||||
import sassjs from './sassjs';
|
|
||||||
import scripts from './scripts';
|
import scripts from './scripts';
|
||||||
|
|
||||||
const metaAndStyleSheets = meta
|
const metaAndStyleSheets = meta
|
||||||
.concat(favicons, mathjax, sassjs, scripts)
|
.concat(favicons, mathjax, scripts)
|
||||||
.map((element, i) => ({
|
.map((element, i) => ({
|
||||||
...element,
|
...element,
|
||||||
key: `meta-stylesheet-${i}`,
|
key: `meta-stylesheet-${i}`,
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
const cdnAddr =
|
|
||||||
'https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.10.9/sass.sync.min.js';
|
|
||||||
|
|
||||||
const sassjs = [<script key='sassjs' src={cdnAddr} type='text/javascript' />];
|
|
||||||
|
|
||||||
export default sassjs;
|
|
@ -16,6 +16,7 @@ import presetReact from '@babel/preset-react';
|
|||||||
import protect from 'loop-protect';
|
import protect from 'loop-protect';
|
||||||
|
|
||||||
import * as vinyl from '../utils/polyvinyl.js';
|
import * as vinyl from '../utils/polyvinyl.js';
|
||||||
|
import WorkerExecutor from '../utils/worker-executor';
|
||||||
|
|
||||||
const protectTimeout = 100;
|
const protectTimeout = 100;
|
||||||
Babel.registerPlugin('loopProtection', protect(protectTimeout));
|
Babel.registerPlugin('loopProtection', protect(protectTimeout));
|
||||||
@ -74,27 +75,21 @@ export const babelTransformer = cond([
|
|||||||
[stubTrue, identity]
|
[stubTrue, identity]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const sass = new WorkerExecutor('sass');
|
||||||
|
|
||||||
const htmlSassTransformCode = file => {
|
const htmlSassTransformCode = file => {
|
||||||
let doc = document.implementation.createHTMLDocument();
|
const div = document.createElement('div');
|
||||||
doc.body.innerHTML = file.contents;
|
div.innerHTML = file.contents;
|
||||||
let styleTags = [].filter.call(
|
const styleTags = div.querySelectorAll('style[type="text/sass"]');
|
||||||
doc.querySelectorAll('style'),
|
if (styleTags.length > 0) {
|
||||||
style => style.type === 'text/sass'
|
return Promise.all([].map.call(styleTags, async style => {
|
||||||
);
|
style.type = 'text/css';
|
||||||
if (styleTags.length === 0 || typeof Sass === 'undefined') {
|
style.innerHTML = await sass.execute(style.innerHTML, 2000);
|
||||||
return vinyl.transformContents(() => doc.body.innerHTML, file);
|
})).then(() => (
|
||||||
|
vinyl.transformContents(() => div.innerHTML, file)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
return Promise.all(styleTags.map(style => (
|
return vinyl.transformContents(() => div.innerHTML, file);
|
||||||
new Promise(resolve => {
|
|
||||||
window.Sass.compile(style.innerHTML, function(result) {
|
|
||||||
style.type = 'text/css';
|
|
||||||
style.innerHTML = result.text;
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
))).then(() => (
|
|
||||||
vinyl.transformContents(() => doc.body.innerHTML, file)
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const htmlSassTransformer = cond([
|
export const htmlSassTransformer = cond([
|
||||||
|
45
client/src/templates/Challenges/utils/worker-executor.js
Normal file
45
client/src/templates/Challenges/utils/worker-executor.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
export default class WorkerExecutor {
|
||||||
|
constructor(workerName) {
|
||||||
|
this.workerName = workerName;
|
||||||
|
this.worker = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWorker() {
|
||||||
|
if (this.worker === null) {
|
||||||
|
this.worker = new Worker(`js/${this.workerName}.js`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
killWorker() {
|
||||||
|
if (this.worker !== null) {
|
||||||
|
this.worker.terminate();
|
||||||
|
this.worker = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
execute(data, timeout = 1000) {
|
||||||
|
const worker = this.getWorker();
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Handle timeout
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
this.killWorker();
|
||||||
|
reject('timeout');
|
||||||
|
}, timeout);
|
||||||
|
|
||||||
|
worker.postMessage(data);
|
||||||
|
|
||||||
|
// Handle result
|
||||||
|
worker.onmessage = e => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
resolve(e.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.onerror = e => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
reject(e.message);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -4,10 +4,12 @@ module.exports = (env = {}) => {
|
|||||||
const __DEV__ = env.production !== true;
|
const __DEV__ = env.production !== true;
|
||||||
return {
|
return {
|
||||||
mode: __DEV__ ? 'development' : 'production',
|
mode: __DEV__ ? 'development' : 'production',
|
||||||
entry: './src/client/frame-runner.js',
|
entry: {
|
||||||
|
'frame-runner': './src/client/frame-runner.js',
|
||||||
|
sass: './src/client/workers/sass.js'
|
||||||
|
},
|
||||||
devtool: __DEV__ ? 'inline-source-map' : 'source-map',
|
devtool: __DEV__ ? 'inline-source-map' : 'source-map',
|
||||||
output: {
|
output: {
|
||||||
filename: 'frame-runner.js',
|
|
||||||
path: path.join(__dirname, './static/js')
|
path: path.join(__dirname, './static/js')
|
||||||
},
|
},
|
||||||
stats: {
|
stats: {
|
||||||
|
Reference in New Issue
Block a user