[Pkg-javascript-devel] Bug#927254: reproducible, but ...
Paolo Greppi
paolo.greppi at libpf.com
Mon Jun 10 14:32:15 BST 2019
Hi, nice one !
It is reproducible when I use the laminar debs built from the WIP package here:
https://salsa.debian.org/debian/laminar
after these fixes:
https://bugs.debian.org/919181#27
Once started, the laminar service dashboard should be reachable from localhost:8080 but it fails to load.
If you open chromium inspector it reports:
vue-router.min.js:10 Uncaught ReferenceError: require is not defined
at vue-router.min.js:10
(anonymous) @ vue-router.min.js:10
app.js:746 Uncaught ReferenceError: Chart is not defined
at app.js:746
(anonymous) @ app.js:746
Navigated to http://10.0.3.188:8080/
vue.min.js:1 You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
Interestingly, laminar package does not depend on libjs-vue-router because the file served from:
http://10.0.3.188:8080/js/vue-router.min.js
gets hard-coded in the /usr/sbin/laminard executable in at build time.
Indeed libjs-vue-router is a mere build-dep for laminar package:
https://salsa.debian.org/debian/laminar/blob/master/debian/control#L15
Currently it is hardcoding vue-router.common.js as vue-router.min.js:
https://salsa.debian.org/debian/laminar/blob/master/debian/patches/0001-Patch-build-system-to-use-JS-libraries-from-Debian-p.patch#L29
which is wrong.
I fixed the JS lib locations like this:
diff --git a/debian/patches/0001-Patch-build-system-to-use-JS-libraries-from-Debian-p.patch b/debian/patches/0001-Patch-build-system-to-use-JS-libraries-from-Debian-p.patch
index 0d6ca8f..e6ffdfe 100644
--- a/debian/patches/0001-Patch-build-system-to-use-JS-libraries-from-Debian-p.patch
+++ b/debian/patches/0001-Patch-build-system-to-use-JS-libraries-from-Debian-p.patch
@@ -26,11 +26,11 @@ index cf73a1b..d18dc65 100644
- css/bootstrap.min.css EXPECTED_MD5 5d5357cb3704e1f43a1f5bfed2aebf42)
+file(DOWNLOAD file:///usr/share/javascript/vue/vue.min.js
+ js/vue.min.js)
-+file(DOWNLOAD file:///usr/share/javascript/vue-router/vue-router.common.js
++file(DOWNLOAD file:///usr/lib/nodejs/vue-router/dist/vue-router.min.js
+ js/vue-router.min.js)
-+file(DOWNLOAD file://usr/share/javascript/ansi_up/ansi_up.min.js
++file(DOWNLOAD file:///usr/share/javascript/ansi_up/ansi_up.min.js
+ js/ansi_up.js)
-+file(DOWNLOAD file://usr/share/javascript/chart.js/Chart.min.js
++file(DOWNLOAD file:///usr/share/javascript/chart.js/Chart.min.js
+ js/Chart.min.js)
+file(DOWNLOAD file://usr/share/javascript/bootstrap/css/bootstrap.min.css
+ css/bootstrap.min.css)
(notice the three forward slashes after file:)
This gets rid of the Chart error, unfortunately for vue-router.min.js, for that I just get a different error in chrome inspector:
vue-router.min.js:791 Uncaught TypeError: Regexp is not a function
at compileRouteRegex (vue-router.min.js:791)
at addRouteRecord (vue-router.min.js:723)
at vue-router.min.js:681
at Array.forEach (<anonymous>)
at createRouteMap (vue-router.min.js:680)
at createMatcher (vue-router.min.js:864)
at new VueRouter (vue-router.min.js:1942)
at app.js:796
compileRouteRegex @ vue-router.min.js:791
addRouteRecord @ vue-router.min.js:723
(anonymous) @ vue-router.min.js:681
createRouteMap @ vue-router.min.js:680
createMatcher @ vue-router.min.js:864
VueRouter @ vue-router.min.js:1942
(anonymous) @ app.js:796
Indeed comparing this file:
https://unpkg.com/vue-router@3.0.2/dist/vue-router.js
with the one packaged by us, they're different.
I attach the diff:
diff vue-router.js_unpkg vue-router.min.js_debian > diff
Paolo
-------------- next part --------------
3c3
< * (c) 2018 Evan You
---
> * (c) 2019 Evan You
7,10c7,12
< typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
< typeof define === 'function' && define.amd ? define(factory) :
< (global.VueRouter = factory());
< }(this, (function () { 'use strict';
---
> typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('path-to-regexp')) :
> typeof define === 'function' && define.amd ? define(['path-to-regexp'], factory) :
> (global.VueRouter = factory(global.Regexp));
> }(this, (function (Regexp) { 'use strict';
>
> Regexp = Regexp && Regexp.hasOwnProperty('default') ? Regexp['default'] : Regexp;
21c23
< if ("development" !== 'production' && !condition) {
---
> if ("production" !== 'production' && !condition) {
127c129
< }
---
> };
140,146c142
< {
< warn(
< false,
< "props in \"" + (route.path) + "\" is a " + (typeof config) + ", " +
< "expecting an object, function or boolean."
< );
< }
---
>
177c173
< "development" !== 'production' && warn(false, e.message);
---
> "production" !== 'production' && warn(false, e.message);
247a244
>
487c484
< }
---
> };
648,1080d644
< var isarray = Array.isArray || function (arr) {
< return Object.prototype.toString.call(arr) == '[object Array]';
< };
<
< /**
< * Expose `pathToRegexp`.
< */
< var pathToRegexp_1 = pathToRegexp;
< var parse_1 = parse;
< var compile_1 = compile;
< var tokensToFunction_1 = tokensToFunction;
< var tokensToRegExp_1 = tokensToRegExp;
<
< /**
< * The main path matching regexp utility.
< *
< * @type {RegExp}
< */
< var PATH_REGEXP = new RegExp([
< // Match escaped characters that would otherwise appear in future matches.
< // This allows the user to escape special characters that won't transform.
< '(\\\\.)',
< // Match Express-style parameters and un-named parameters with a prefix
< // and optional suffixes. Matches appear as:
< //
< // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
< // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
< // "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
< '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
< ].join('|'), 'g');
<
< /**
< * Parse a string for the raw tokens.
< *
< * @param {string} str
< * @param {Object=} options
< * @return {!Array}
< */
< function parse (str, options) {
< var tokens = [];
< var key = 0;
< var index = 0;
< var path = '';
< var defaultDelimiter = options && options.delimiter || '/';
< var res;
<
< while ((res = PATH_REGEXP.exec(str)) != null) {
< var m = res[0];
< var escaped = res[1];
< var offset = res.index;
< path += str.slice(index, offset);
< index = offset + m.length;
<
< // Ignore already escaped sequences.
< if (escaped) {
< path += escaped[1];
< continue
< }
<
< var next = str[index];
< var prefix = res[2];
< var name = res[3];
< var capture = res[4];
< var group = res[5];
< var modifier = res[6];
< var asterisk = res[7];
<
< // Push the current path onto the tokens.
< if (path) {
< tokens.push(path);
< path = '';
< }
<
< var partial = prefix != null && next != null && next !== prefix;
< var repeat = modifier === '+' || modifier === '*';
< var optional = modifier === '?' || modifier === '*';
< var delimiter = res[2] || defaultDelimiter;
< var pattern = capture || group;
<
< tokens.push({
< name: name || key++,
< prefix: prefix || '',
< delimiter: delimiter,
< optional: optional,
< repeat: repeat,
< partial: partial,
< asterisk: !!asterisk,
< pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
< });
< }
<
< // Match any characters still remaining.
< if (index < str.length) {
< path += str.substr(index);
< }
<
< // If the path exists, push it onto the end.
< if (path) {
< tokens.push(path);
< }
<
< return tokens
< }
<
< /**
< * Compile a string to a template function for the path.
< *
< * @param {string} str
< * @param {Object=} options
< * @return {!function(Object=, Object=)}
< */
< function compile (str, options) {
< return tokensToFunction(parse(str, options))
< }
<
< /**
< * Prettier encoding of URI path segments.
< *
< * @param {string}
< * @return {string}
< */
< function encodeURIComponentPretty (str) {
< return encodeURI(str).replace(/[\/?#]/g, function (c) {
< return '%' + c.charCodeAt(0).toString(16).toUpperCase()
< })
< }
<
< /**
< * Encode the asterisk parameter. Similar to `pretty`, but allows slashes.
< *
< * @param {string}
< * @return {string}
< */
< function encodeAsterisk (str) {
< return encodeURI(str).replace(/[?#]/g, function (c) {
< return '%' + c.charCodeAt(0).toString(16).toUpperCase()
< })
< }
<
< /**
< * Expose a method for transforming tokens into the path function.
< */
< function tokensToFunction (tokens) {
< // Compile all the tokens into regexps.
< var matches = new Array(tokens.length);
<
< // Compile all the patterns before compilation.
< for (var i = 0; i < tokens.length; i++) {
< if (typeof tokens[i] === 'object') {
< matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
< }
< }
<
< return function (obj, opts) {
< var path = '';
< var data = obj || {};
< var options = opts || {};
< var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent;
<
< for (var i = 0; i < tokens.length; i++) {
< var token = tokens[i];
<
< if (typeof token === 'string') {
< path += token;
<
< continue
< }
<
< var value = data[token.name];
< var segment;
<
< if (value == null) {
< if (token.optional) {
< // Prepend partial segment prefixes.
< if (token.partial) {
< path += token.prefix;
< }
<
< continue
< } else {
< throw new TypeError('Expected "' + token.name + '" to be defined')
< }
< }
<
< if (isarray(value)) {
< if (!token.repeat) {
< throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
< }
<
< if (value.length === 0) {
< if (token.optional) {
< continue
< } else {
< throw new TypeError('Expected "' + token.name + '" to not be empty')
< }
< }
<
< for (var j = 0; j < value.length; j++) {
< segment = encode(value[j]);
<
< if (!matches[i].test(segment)) {
< throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
< }
<
< path += (j === 0 ? token.prefix : token.delimiter) + segment;
< }
<
< continue
< }
<
< segment = token.asterisk ? encodeAsterisk(value) : encode(value);
<
< if (!matches[i].test(segment)) {
< throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
< }
<
< path += token.prefix + segment;
< }
<
< return path
< }
< }
<
< /**
< * Escape a regular expression string.
< *
< * @param {string} str
< * @return {string}
< */
< function escapeString (str) {
< return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1')
< }
<
< /**
< * Escape the capturing group by escaping special characters and meaning.
< *
< * @param {string} group
< * @return {string}
< */
< function escapeGroup (group) {
< return group.replace(/([=!:$\/()])/g, '\\$1')
< }
<
< /**
< * Attach the keys as a property of the regexp.
< *
< * @param {!RegExp} re
< * @param {Array} keys
< * @return {!RegExp}
< */
< function attachKeys (re, keys) {
< re.keys = keys;
< return re
< }
<
< /**
< * Get the flags for a regexp from the options.
< *
< * @param {Object} options
< * @return {string}
< */
< function flags (options) {
< return options.sensitive ? '' : 'i'
< }
<
< /**
< * Pull out keys from a regexp.
< *
< * @param {!RegExp} path
< * @param {!Array} keys
< * @return {!RegExp}
< */
< function regexpToRegexp (path, keys) {
< // Use a negative lookahead to match only capturing groups.
< var groups = path.source.match(/\((?!\?)/g);
<
< if (groups) {
< for (var i = 0; i < groups.length; i++) {
< keys.push({
< name: i,
< prefix: null,
< delimiter: null,
< optional: false,
< repeat: false,
< partial: false,
< asterisk: false,
< pattern: null
< });
< }
< }
<
< return attachKeys(path, keys)
< }
<
< /**
< * Transform an array into a regexp.
< *
< * @param {!Array} path
< * @param {Array} keys
< * @param {!Object} options
< * @return {!RegExp}
< */
< function arrayToRegexp (path, keys, options) {
< var parts = [];
<
< for (var i = 0; i < path.length; i++) {
< parts.push(pathToRegexp(path[i], keys, options).source);
< }
<
< var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options));
<
< return attachKeys(regexp, keys)
< }
<
< /**
< * Create a path regexp from string input.
< *
< * @param {string} path
< * @param {!Array} keys
< * @param {!Object} options
< * @return {!RegExp}
< */
< function stringToRegexp (path, keys, options) {
< return tokensToRegExp(parse(path, options), keys, options)
< }
<
< /**
< * Expose a function for taking tokens and returning a RegExp.
< *
< * @param {!Array} tokens
< * @param {(Array|Object)=} keys
< * @param {Object=} options
< * @return {!RegExp}
< */
< function tokensToRegExp (tokens, keys, options) {
< if (!isarray(keys)) {
< options = /** @type {!Object} */ (keys || options);
< keys = [];
< }
<
< options = options || {};
<
< var strict = options.strict;
< var end = options.end !== false;
< var route = '';
<
< // Iterate over the tokens and create our regexp string.
< for (var i = 0; i < tokens.length; i++) {
< var token = tokens[i];
<
< if (typeof token === 'string') {
< route += escapeString(token);
< } else {
< var prefix = escapeString(token.prefix);
< var capture = '(?:' + token.pattern + ')';
<
< keys.push(token);
<
< if (token.repeat) {
< capture += '(?:' + prefix + capture + ')*';
< }
<
< if (token.optional) {
< if (!token.partial) {
< capture = '(?:' + prefix + '(' + capture + '))?';
< } else {
< capture = prefix + '(' + capture + ')?';
< }
< } else {
< capture = prefix + '(' + capture + ')';
< }
<
< route += capture;
< }
< }
<
< var delimiter = escapeString(options.delimiter || '/');
< var endsWithDelimiter = route.slice(-delimiter.length) === delimiter;
<
< // In non-strict mode we allow a slash at the end of match. If the path to
< // match already ends with a slash, we remove it for consistency. The slash
< // is valid at the end of a path match, not in the middle. This is important
< // in non-ending mode, where "/test/" shouldn't match "/test//route".
< if (!strict) {
< route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?';
< }
<
< if (end) {
< route += '$';
< } else {
< // In non-ending mode, we need the capturing groups to match as much as
< // possible by using a positive lookahead to the end or next path segment.
< route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)';
< }
<
< return attachKeys(new RegExp('^' + route, flags(options)), keys)
< }
<
< /**
< * Normalize the given path string, returning a regular expression.
< *
< * An empty array can be passed in for the keys, which will hold the
< * placeholder key descriptions. For example, using `/user/:id`, `keys` will
< * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
< *
< * @param {(string|RegExp|Array)} path
< * @param {(Array|Object)=} keys
< * @param {Object=} options
< * @return {!RegExp}
< */
< function pathToRegexp (path, keys, options) {
< if (!isarray(keys)) {
< options = /** @type {!Object} */ (keys || options);
< keys = [];
< }
<
< options = options || {};
<
< if (path instanceof RegExp) {
< return regexpToRegexp(path, /** @type {!Array} */ (keys))
< }
<
< if (isarray(path)) {
< return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
< }
<
< return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
< }
< pathToRegexp_1.parse = parse_1;
< pathToRegexp_1.compile = compile_1;
< pathToRegexp_1.tokensToFunction = tokensToFunction_1;
< pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
<
1094c658
< (regexpCompileCache[path] = pathToRegexp_1.compile(path));
---
> (regexpCompileCache[path] = Regexp.compile(path));
1097,1099d660
< {
< warn(false, ("missing param for " + routeMsg + ": " + (e.message)));
< }
1149,1157d709
< {
< assert(path != null, "\"path\" is required in a route configuration.");
< assert(
< typeof route.component !== 'string',
< "route config \"component\" for path: " + (String(path || name)) + " cannot be a " +
< "string id. Use an actual component instead."
< );
< }
<
1191,1202d742
< {
< if (route.name && !route.redirect && route.children.some(function (child) { return /^\/?$/.test(child.path); })) {
< warn(
< false,
< "Named Route '" + (route.name) + "' has a default child route. " +
< "When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " +
< "the default child route will not be rendered. Remove the name from " +
< "this route and use the name of the default child route for named " +
< "links instead."
< );
< }
< }
1240c780
< } else if ("development" !== 'production' && !matchAs) {
---
> } else if ("production" !== 'production' && !matchAs) {
1251,1258c791
< var regex = pathToRegexp_1(path, [], pathToRegexpOptions);
< {
< var keys = Object.create(null);
< regex.keys.forEach(function (key) {
< warn(!keys[key.name], ("Duplicate param keys in route with path: \"" + path + "\""));
< keys[key.name] = true;
< });
< }
---
> var regex = Regexp(path, [], pathToRegexpOptions);
1270a804
>
1294,1296c828
< } else {
< warn(false, "relative params navigation requires a current route.");
< }
---
> } else {}
1328d859
<
1352,1354d882
< {
< warn(record, ("Route with name '" + name + "' does not exist"));
< }
1404,1408d931
< {
< warn(
< false, ("invalid redirect option: " + (JSON.stringify(redirect)))
< );
< }
1424,1427d946
< var targetRecord = nameMap[name];
< {
< assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."));
< }
1448,1450d966
< {
< warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))));
< }
1524a1041
>
1554,1558d1070
< {
< assert(typeof behavior === 'function', "scrollBehavior must be a function");
< }
<
< // wait until re-render finishes before scrolling
1571,1573c1083
< {
< assert(false, err.toString());
< }
---
>
1761c1271
< "development" !== 'production' && warn(false, msg);
---
> "production" !== 'production' && warn(false, msg);
2136a1647
>
2224a1736
>
2361a1874
>
2420,2421d1932
<
<
2454,2456c1965
< {
< assert(false, ("invalid mode: " + mode));
< }
---
>
2477c1986
< "development" !== 'production' && assert(
---
> "production" !== 'production' && assert(
2626a2136
> //# sourceMappingURL=vue-router.min.js.map
More information about the Pkg-javascript-devel
mailing list