Webpack dev server (#902)

* Initial webpack config. Moving to ES6 modules. Some module cleanup.

* WIP

* WIP

* Removing commented out code.

* Removing old deps.

* Removing the build script (used for testing).

* Working tests.

* Switching to node api over cli.

* Updating per comments. Still need to fix server.js to properly run the selenium tests.

* Cleaning up the config.

* More cleanup.

* Bringing back server.js for selenium tests.

* Bringing back old dependencies.

* Adding back eslint rules for webpack config. Final cleanup for webpack config.

* Pointing to correct pre-existing module versions. Adding some extra logic to server.js to ensure it gets transpiled properly.

* Getting make build to work again. Updating package.json with some shortcut scripts.

* Resolving conflict.

* Reverting back to commonjs modules.

* Removing extra spaces in babelrc
This commit is contained in:
Ryan Randall
2017-09-26 14:16:35 -04:00
committed by Kevin Barabash
parent eaef0127c5
commit fbffdc5fc7
32 changed files with 154 additions and 59 deletions

View File

View File

@@ -1,7 +1,7 @@
/* eslint no-console:0 */
/* global katex */
const splitAtDelimiters = require("./splitAtDelimiters");
import splitAtDelimiters from "./splitAtDelimiters";
const splitWithDelimiters = function(text, delimiters) {
let data = [{type: "text", data: text}];
@@ -99,4 +99,5 @@ const renderMathInElement = function(elem, options) {
renderElem(elem, optionsCopy);
};
module.exports = renderMathInElement;
export default renderMathInElement;

View File

@@ -99,4 +99,4 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
return finalData;
};
module.exports = splitAtDelimiters;
export default splitAtDelimiters;

View File

@@ -1,4 +1,4 @@
const katexReplaceWithTex = require('./katex2tex');
import katexReplaceWithTex from './katex2tex';
// Global copy handler to modify behavior on .katex elements.
document.addEventListener('copy', function(event) {

View File

@@ -49,4 +49,4 @@ export const katexReplaceWithTex = function(fragment,
return fragment;
};
module.exports = katexReplaceWithTex;
export default katexReplaceWithTex;

View File

@@ -43,6 +43,7 @@ if (typeof document !== "undefined") {
}
}
/**
* Parse and build an expression, and return the markup for that.
*/
@@ -61,7 +62,8 @@ const generateParseTree = function(expression, options) {
return parseTree(expression, settings);
};
module.exports = {
const katex = {
render: render,
renderToString: renderToString,
/**
@@ -72,3 +74,5 @@ module.exports = {
__parse: generateParseTree,
ParseError: ParseError,
};
export default katex;

View File

@@ -18,6 +18,8 @@
"devDependencies": {
"babel-eslint": "^7.2.0",
"babel-jest": "^20.0.3",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-class-properties": "^6.23.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.18.0",
@@ -37,6 +39,7 @@
"js-yaml": "^3.3.1",
"jspngopt": "^0.2.0",
"less": "~2.7.1",
"less-plugin-clean-css": "^1.5.1",
"morgan": "^1.7.0",
"nomnom": "^1.8.1",
"object-assign": "^4.1.0",
@@ -44,7 +47,9 @@
"pre-commit": "^1.2.2",
"selenium-webdriver": "^2.48.2",
"sri-toolbox": "^0.2.0",
"uglify-js": "~2.7.5"
"uglify-js": "~2.7.5",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.8.2"
},
"bin": "cli.js",
"scripts": {
@@ -52,8 +57,13 @@
"flow": "flow",
"jest": "jest",
"coverage": "jest --coverage",
"copy": "cp -a static/. build/ && cp -a contrib build/",
"clean": "rm -rf build/* node_modules/",
"clean-install": "npm run clean && npm i",
"test": "check-dependencies && npm run lint && npm run flow && npm run jest",
"start": "check-dependencies && node server.js",
"build-css": "lessc --clean-css static/katex.less build/katex.css",
"prestart": "npm run build-css && npm run copy",
"start": "check-dependencies && node webpackDevServer.js",
"prepublishOnly": "make NIS= dist"
},
"pre-commit": [

View File

@@ -27,7 +27,14 @@ function serveBrowserified(file, standaloneName) {
}
const options = {
transform: [babelify],
transform: [babelify.configure({
presets: ["es2015", "flow"],
plugins: [
"transform-runtime",
"transform-class-properties",
"add-module-exports",
],
})],
};
if (standaloneName) {
options.standalone = standaloneName;

View File

@@ -304,4 +304,4 @@ class Options {
}
}
module.exports = Options;
export default Options;

View File

@@ -72,4 +72,4 @@ class ParseError {
// $FlowFixMe More hackery
ParseError.prototype.__proto__ = Error.prototype;
module.exports = ParseError;
export default ParseError;

View File

@@ -928,7 +928,7 @@ export default class Parser {
// Lexer's tokenRegex is constructed to always have matching
// first/last characters.
if (arg.length < 2 || arg.charAt(0) !== arg.slice(-1)) {
throw new ParseError(`\\verb assertion failed --
throw new ParseError(`\\verb assertion failed --
please report what input caused this bug`);
}
arg = arg.slice(1, -1); // remove first and last char

View File

@@ -45,4 +45,4 @@ class Settings {
}
}
module.exports = Settings;
export default Settings;

View File

@@ -122,7 +122,7 @@ const cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc];
const text = [D, Dc, T, Tc, T, Tc, T, Tc];
// We only export some of the styles.
module.exports = {
export default {
DISPLAY: styles[D],
TEXT: styles[T],
SCRIPT: styles[S],

View File

@@ -505,7 +505,7 @@ const fontMap = {
},
};
module.exports = {
export default {
fontMap: fontMap,
makeSymbol: makeSymbol,
mathsym: mathsym,

View File

@@ -10,13 +10,15 @@
import ParseError from "./ParseError";
import Style from "./Style";
import buildCommon, { makeSpan } from "./buildCommon";
import buildCommon from "./buildCommon";
import delimiter from "./delimiter";
import domTree from "./domTree";
import { calculateSize } from "./units";
import utils from "./utils";
import stretchy from "./stretchy";
const makeSpan = buildCommon.makeSpan;
const isSpace = function(node) {
return node instanceof domTree.span && node.classes[0] === "mspace";
};

View File

@@ -6,7 +6,7 @@
* parser.
*/
import buildCommon, { makeSpan, fontMap } from "./buildCommon";
import buildCommon from "./buildCommon";
import fontMetrics from "./fontMetrics";
import mathMLTree from "./mathMLTree";
import ParseError from "./ParseError";
@@ -50,9 +50,9 @@ const getVariant = function(group, options) {
value = symbols[mode][value].replace;
}
const fontName = fontMap[font].fontName;
const fontName = buildCommon.fontMap[font].fontName;
if (fontMetrics.getCharacterMetrics(value, fontName)) {
return fontMap[options.font].variant;
return buildCommon.fontMap[options.font].variant;
}
return null;
@@ -458,7 +458,7 @@ groupTypes.sizing = function(group, options) {
groupTypes.verb = function(group, options) {
const text = new mathMLTree.TextNode(buildCommon.makeVerb(group, options));
const node = new mathMLTree.MathNode("mtext", [text]);
node.setAttribute("mathvariant", fontMap["mathtt"].variant);
node.setAttribute("mathvariant", buildCommon.fontMap["mathtt"].variant);
return node;
};
@@ -690,5 +690,5 @@ export default function buildMathML(tree, texExpression, options) {
const math = new mathMLTree.MathNode("math", [semantics]);
// You can't style <math> nodes, so we wrap the node in a span.
return makeSpan(["katex-mathml"], [math]);
return buildCommon.makeSpan(["katex-mathml"], [math]);
}

View File

@@ -1,6 +1,6 @@
import buildHTML from "./buildHTML";
import buildMathML from "./buildMathML";
import { makeSpan } from "./buildCommon";
import buildCommon from "./buildCommon";
import Options from "./Options";
import Settings from "./Settings";
import Style from "./Style";
@@ -24,15 +24,15 @@ const buildTree = function(tree, expression, settings) {
const mathMLNode = buildMathML(tree, expression, options);
const htmlNode = buildHTML(tree, options);
const katexNode = makeSpan(["katex"], [
const katexNode = buildCommon.makeSpan(["katex"], [
mathMLNode, htmlNode,
]);
if (settings.displayMode) {
return makeSpan(["katex-display"], [katexNode]);
return buildCommon.makeSpan(["katex-display"], [katexNode]);
} else {
return katexNode;
}
};
module.exports = buildTree;
export default buildTree;

View File

@@ -24,7 +24,7 @@ import ParseError from "./ParseError";
import Style from "./Style";
import domTree from "./domTree";
import buildCommon, { makeSpan } from "./buildCommon";
import buildCommon from "./buildCommon";
import fontMetrics from "./fontMetrics";
import symbols from "./symbols";
import utils from "./utils";
@@ -50,7 +50,7 @@ const getMetrics = function(symbol, font) {
const styleWrap = function(delim, toStyle, options, classes) {
const newOptions = options.havingBaseStyle(toStyle);
const span = makeSpan(
const span = buildCommon.makeSpan(
(classes || []).concat(newOptions.sizingClasses(options)),
[delim], options);
@@ -103,7 +103,7 @@ const mathrmSize = function(value, size, mode, options) {
const makeLargeDelim = function(delim, size, center, options, mode, classes) {
const inner = mathrmSize(delim, size, mode, options);
const span = styleWrap(
makeSpan(["delimsizing", "size" + size], [inner], options),
buildCommon.makeSpan(["delimsizing", "size" + size], [inner], options),
Style.TEXT, options, classes);
if (center) {
centerSpan(span, options, Style.TEXT);
@@ -124,9 +124,9 @@ const makeInner = function(symbol, font, mode) {
sizeClass = "delim-size4";
}
const inner = makeSpan(
const inner = buildCommon.makeSpan(
["delimsizinginner", sizeClass],
[makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]);
[buildCommon.makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]);
// Since this will be passed into `makeVList` in the end, wrap the element
// in the appropriate tag that VList uses.
@@ -310,7 +310,7 @@ const makeStackedDelim = function(delim, heightTotal, center, options, mode,
const inner = buildCommon.makeVList(inners, "bottom", depth, newOptions);
return styleWrap(
makeSpan(["delimsizing", "mult"], [inner], newOptions),
buildCommon.makeSpan(["delimsizing", "mult"], [inner], newOptions),
Style.TEXT, options, classes);
};
@@ -606,7 +606,7 @@ const makeLeftRightDelim = function(delim, height, depth, options, mode,
classes);
};
module.exports = {
export default {
sizedDelim: makeSizedDelim,
customSizedDelim: makeCustomSizedDelim,
leftRightDelim: makeLeftRightDelim,

View File

@@ -443,7 +443,7 @@ class lineNode {
}
}
module.exports = {
export default {
span: span,
documentFragment: documentFragment,
symbolNode: symbolNode,

View File

@@ -10,7 +10,7 @@ const environments = {
},
};
export {environments as default};
export default environments;
// All environment definitions should be imported below
import "./environments/array.js";

View File

@@ -1,5 +1,5 @@
// @flow
import buildCommon, {makeSpan} from "../buildCommon";
import buildCommon from "../buildCommon";
import defineEnvironment from "../defineEnvironment";
import mathMLTree from "../mathMLTree";
import ParseError from "../ParseError";
@@ -191,14 +191,14 @@ const htmlBuilder = function(group, options) {
// If there is more than one separator in a row, add a space
// between them.
if (!firstSeparator) {
colSep = makeSpan(["arraycolsep"], []);
colSep = buildCommon.makeSpan(["arraycolsep"], []);
colSep.style.width =
options.fontMetrics().doubleRuleSep + "em";
cols.push(colSep);
}
if (colDescr.separator === "|") {
const separator = makeSpan(
const separator = buildCommon.makeSpan(
["vertical-separator"],
[]);
separator.style.height = totalHeight + "em";
@@ -224,7 +224,7 @@ const htmlBuilder = function(group, options) {
if (c > 0 || group.value.hskipBeforeAndAfter) {
sepwidth = utils.deflt(colDescr.pregap, arraycolsep);
if (sepwidth !== 0) {
colSep = makeSpan(["arraycolsep"], []);
colSep = buildCommon.makeSpan(["arraycolsep"], []);
colSep.style.width = sepwidth + "em";
cols.push(colSep);
}
@@ -244,7 +244,7 @@ const htmlBuilder = function(group, options) {
}
col = buildCommon.makeVList(col, "individualShift", null, options);
col = makeSpan(
col = buildCommon.makeSpan(
["col-align-" + (colDescr.align || "c")],
[col]);
cols.push(col);
@@ -252,14 +252,14 @@ const htmlBuilder = function(group, options) {
if (c < nc - 1 || group.value.hskipBeforeAndAfter) {
sepwidth = utils.deflt(colDescr.postgap, arraycolsep);
if (sepwidth !== 0) {
colSep = makeSpan(["arraycolsep"], []);
colSep = buildCommon.makeSpan(["arraycolsep"], []);
colSep.style.width = sepwidth + "em";
cols.push(colSep);
}
}
}
body = makeSpan(["mtable"], cols);
return makeSpan(["mord"], [body], options);
body = buildCommon.makeSpan(["mtable"], cols);
return buildCommon.makeSpan(["mord"], [body], options);
};
const mathmlBuilder = function(group, options) {

View File

@@ -297,7 +297,7 @@ const getFontMetrics = function(size: number): FontMetrics {
return fontMetricsBySizeIndex[sizeIndex];
};
module.exports = {
export default {
getFontMetrics: getFontMetrics,
getCharacterMetrics: getCharacterMetrics,
};

View File

@@ -1755,4 +1755,4 @@ const fontMetricsData = {
},
};
module.exports = fontMetricsData;
export default fontMetricsData;

View File

@@ -1,5 +1,5 @@
// @flow
import buildCommon, {makeSpan} from "../buildCommon";
import buildCommon from "../buildCommon";
import defineFunction from "../defineFunction";
import delimiter from "../delimiter";
import mathMLTree from "../mathMLTree";
@@ -85,7 +85,7 @@ defineFunction({
if (delim === ".") {
// Empty delimiters still count as elements, even though they don't
// show anything.
return makeSpan([group.value.mclass]);
return buildCommon.makeSpan([group.value.mclass]);
}
// Use delimiter.sizedDelim to generate the delimiter.
@@ -203,7 +203,7 @@ defineFunction({
// Add it to the end of the expression.
inner.push(rightDelim);
return makeSpan(["minner"], inner, options);
return buildCommon.makeSpan(["minner"], inner, options);
},
mathmlBuilder: (group, options) => {
const inner = mml.buildExpression(group.value.body, options);

View File

@@ -100,7 +100,7 @@ class TextNode {
}
}
module.exports = {
export default {
MathNode: MathNode,
TextNode: TextNode,
};

View File

@@ -17,4 +17,4 @@ const parseTree = function(toParse, settings) {
return parser.parse();
};
module.exports = parseTree;
export default parseTree;

View File

@@ -4,10 +4,10 @@
* and other CSS trickery.
*/
const domTree = require("./domTree");
const buildCommon = require("./buildCommon");
const mathMLTree = require("./mathMLTree");
const utils = require("./utils");
import domTree from "./domTree";
import buildCommon from "./buildCommon";
import mathMLTree from "./mathMLTree";
import utils from "./utils";
const stretchyCodePoint = {
widehat: "^",
@@ -311,7 +311,7 @@ const encloseSpan = function(inner, label, pad, options) {
return img;
};
module.exports = {
export default {
encloseSpan: encloseSpan,
mathMLnode: mathMLnode,
svgSpan: svgSpan,

View File

@@ -261,6 +261,6 @@ c-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`,
-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`,
};
module.exports = {
export default {
path: path,
};

View File

@@ -94,7 +94,7 @@ function clearNode(node) {
setTextContent(node, "");
}
module.exports = {
export default {
contains: contains,
deflt: deflt,
escape: escape,

View File

@@ -3,9 +3,9 @@
/* global expect: false */
/* global it: false */
/* global describe: false */
const ParseError = require("../src/ParseError");
const parseTree = require("../src/parseTree");
const Settings = require("../src/Settings");
import ParseError from "../src/ParseError";
import parseTree from "../src/parseTree";
import Settings from "../src/Settings";
const defaultSettings = new Settings({});

59
webpack.config.js Normal file
View File

@@ -0,0 +1,59 @@
const path = require('path');
const katexConfig = {
entry: ['./katex.js'],
output: {
path: path.join(__dirname, 'build'),
filename: 'katex.js',
library: 'katex',
libraryTarget: 'umd',
libraryExport: 'default',
},
};
const copyTexConfig = {
entry: ['./contrib/copy-tex/copy-tex.js'],
output: {
path: path.join(__dirname, 'build', 'contrib', 'copy-tex'),
filename: 'copy-tex.js',
},
};
const autoRenderConfig = {
entry: ['./contrib/auto-render/auto-render.js'],
output: {
path: path.join(__dirname, 'build', 'contrib', 'auto-render'),
filename: 'auto-render.js',
library: 'renderMathInElement',
libraryTarget: 'umd',
libraryExport: 'default',
},
};
const commonConfig = {
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules\//,
},
],
},
devtool: 'eval-source-map',
};
module.exports = {
compilerConfig: [
Object.assign({}, katexConfig, commonConfig),
Object.assign({}, copyTexConfig, commonConfig),
Object.assign({}, autoRenderConfig, commonConfig),
],
devServerConfig: {
publicPath: '/',
contentBase: path.join(__dirname, 'build'),
stats: {
colors: true,
},
},
};

12
webpackDevServer.js Normal file
View File

@@ -0,0 +1,12 @@
const WebpackDevServer = require("webpack-dev-server");
const webpack = require("webpack");
const webpackConfig = require("./webpack.config.js");
const PORT = 7936;
webpackConfig.compilerConfig.forEach((config) => {
config.entry.unshift(`webpack-dev-server/client?http://localhost:${PORT}/`);
});
const compiler = webpack(webpackConfig.compilerConfig);
const server = new WebpackDevServer(compiler, webpackConfig.devServerConfig);
server.listen(PORT);