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

View File

@@ -99,4 +99,4 @@ const splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
return finalData; 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. // Global copy handler to modify behavior on .katex elements.
document.addEventListener('copy', function(event) { document.addEventListener('copy', function(event) {

View File

@@ -49,4 +49,4 @@ export const katexReplaceWithTex = function(fragment,
return 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. * Parse and build an expression, and return the markup for that.
*/ */
@@ -61,7 +62,8 @@ const generateParseTree = function(expression, options) {
return parseTree(expression, settings); return parseTree(expression, settings);
}; };
module.exports = {
const katex = {
render: render, render: render,
renderToString: renderToString, renderToString: renderToString,
/** /**
@@ -72,3 +74,5 @@ module.exports = {
__parse: generateParseTree, __parse: generateParseTree,
ParseError: ParseError, ParseError: ParseError,
}; };
export default katex;

View File

@@ -18,6 +18,8 @@
"devDependencies": { "devDependencies": {
"babel-eslint": "^7.2.0", "babel-eslint": "^7.2.0",
"babel-jest": "^20.0.3", "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-class-properties": "^6.23.0",
"babel-plugin-transform-runtime": "^6.15.0", "babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.18.0", "babel-preset-es2015": "^6.18.0",
@@ -37,6 +39,7 @@
"js-yaml": "^3.3.1", "js-yaml": "^3.3.1",
"jspngopt": "^0.2.0", "jspngopt": "^0.2.0",
"less": "~2.7.1", "less": "~2.7.1",
"less-plugin-clean-css": "^1.5.1",
"morgan": "^1.7.0", "morgan": "^1.7.0",
"nomnom": "^1.8.1", "nomnom": "^1.8.1",
"object-assign": "^4.1.0", "object-assign": "^4.1.0",
@@ -44,7 +47,9 @@
"pre-commit": "^1.2.2", "pre-commit": "^1.2.2",
"selenium-webdriver": "^2.48.2", "selenium-webdriver": "^2.48.2",
"sri-toolbox": "^0.2.0", "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", "bin": "cli.js",
"scripts": { "scripts": {
@@ -52,8 +57,13 @@
"flow": "flow", "flow": "flow",
"jest": "jest", "jest": "jest",
"coverage": "jest --coverage", "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", "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" "prepublishOnly": "make NIS= dist"
}, },
"pre-commit": [ "pre-commit": [

View File

@@ -27,7 +27,14 @@ function serveBrowserified(file, standaloneName) {
} }
const options = { const options = {
transform: [babelify], transform: [babelify.configure({
presets: ["es2015", "flow"],
plugins: [
"transform-runtime",
"transform-class-properties",
"add-module-exports",
],
})],
}; };
if (standaloneName) { if (standaloneName) {
options.standalone = 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 // $FlowFixMe More hackery
ParseError.prototype.__proto__ = Error.prototype; 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 // Lexer's tokenRegex is constructed to always have matching
// first/last characters. // first/last characters.
if (arg.length < 2 || arg.charAt(0) !== arg.slice(-1)) { 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`); please report what input caused this bug`);
} }
arg = arg.slice(1, -1); // remove first and last char 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]; const text = [D, Dc, T, Tc, T, Tc, T, Tc];
// We only export some of the styles. // We only export some of the styles.
module.exports = { export default {
DISPLAY: styles[D], DISPLAY: styles[D],
TEXT: styles[T], TEXT: styles[T],
SCRIPT: styles[S], SCRIPT: styles[S],

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
* parser. * parser.
*/ */
import buildCommon, { makeSpan, fontMap } from "./buildCommon"; import buildCommon from "./buildCommon";
import fontMetrics from "./fontMetrics"; import fontMetrics from "./fontMetrics";
import mathMLTree from "./mathMLTree"; import mathMLTree from "./mathMLTree";
import ParseError from "./ParseError"; import ParseError from "./ParseError";
@@ -50,9 +50,9 @@ const getVariant = function(group, options) {
value = symbols[mode][value].replace; value = symbols[mode][value].replace;
} }
const fontName = fontMap[font].fontName; const fontName = buildCommon.fontMap[font].fontName;
if (fontMetrics.getCharacterMetrics(value, fontName)) { if (fontMetrics.getCharacterMetrics(value, fontName)) {
return fontMap[options.font].variant; return buildCommon.fontMap[options.font].variant;
} }
return null; return null;
@@ -458,7 +458,7 @@ groupTypes.sizing = function(group, options) {
groupTypes.verb = function(group, options) { groupTypes.verb = function(group, options) {
const text = new mathMLTree.TextNode(buildCommon.makeVerb(group, options)); const text = new mathMLTree.TextNode(buildCommon.makeVerb(group, options));
const node = new mathMLTree.MathNode("mtext", [text]); const node = new mathMLTree.MathNode("mtext", [text]);
node.setAttribute("mathvariant", fontMap["mathtt"].variant); node.setAttribute("mathvariant", buildCommon.fontMap["mathtt"].variant);
return node; return node;
}; };
@@ -690,5 +690,5 @@ export default function buildMathML(tree, texExpression, options) {
const math = new mathMLTree.MathNode("math", [semantics]); const math = new mathMLTree.MathNode("math", [semantics]);
// You can't style <math> nodes, so we wrap the node in a span. // 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 buildHTML from "./buildHTML";
import buildMathML from "./buildMathML"; import buildMathML from "./buildMathML";
import { makeSpan } from "./buildCommon"; import buildCommon from "./buildCommon";
import Options from "./Options"; import Options from "./Options";
import Settings from "./Settings"; import Settings from "./Settings";
import Style from "./Style"; import Style from "./Style";
@@ -24,15 +24,15 @@ const buildTree = function(tree, expression, settings) {
const mathMLNode = buildMathML(tree, expression, options); const mathMLNode = buildMathML(tree, expression, options);
const htmlNode = buildHTML(tree, options); const htmlNode = buildHTML(tree, options);
const katexNode = makeSpan(["katex"], [ const katexNode = buildCommon.makeSpan(["katex"], [
mathMLNode, htmlNode, mathMLNode, htmlNode,
]); ]);
if (settings.displayMode) { if (settings.displayMode) {
return makeSpan(["katex-display"], [katexNode]); return buildCommon.makeSpan(["katex-display"], [katexNode]);
} else { } else {
return katexNode; return katexNode;
} }
}; };
module.exports = buildTree; export default buildTree;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,9 +3,9 @@
/* global expect: false */ /* global expect: false */
/* global it: false */ /* global it: false */
/* global describe: false */ /* global describe: false */
const ParseError = require("../src/ParseError"); import ParseError from "../src/ParseError";
const parseTree = require("../src/parseTree"); import parseTree from "../src/parseTree";
const Settings = require("../src/Settings"); import Settings from "../src/Settings";
const defaultSettings = new 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);