I have 'npm install -S tabletop' into my vuepress site and I am struggling to either import or require the tabletop module.
I know next to nothing about webpack nor the internals of vuepress (this is nmy first vuepress project)
Building a static website for a friend but planning to use a google spreadsheet to hold current work opportunities and suck the line entries using tabletop.js (https://www.npmjs.com/package/tabletop) into a JSON then filter and loop through to present in a vuepress loop
However, I've failed at step one of this process ... using tabletop.js inside a vuepress container's tag
Hi all, I'm new to vuepress and webpack and I'm getting a headache over trying to use a javascript library. I'm familiar with javascript and writing my own scripts and also loading javascript libraries in raw html websites. But I've really got stuck trying to figure out where the relative path for a require statement should be
I've tried both npm installing and also inserting into the config.js HEAD (which appears in devtools) options 1 and/or 2 below
install tabletop.js with
npm install -S tabletop
2.add link to config.js' HEAD
module.exports = {
title: 'Starlife Company Services Ltd',
description: 'Cleaning and Security services across the South East',
head: [
['link', { type: 'text/javscript', src: 'https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js' }]
]
}
add a require in tags in component
<template>
....
</template>
<script>
export default {
name: "cleaning-cta"
};
console.log("script started from inside joblist.vue")
import as sheet from 'tabletop'
var recruitment = "https://docs.google.com/spreadsheets/d/1M7glQxJb31B3lQyKNqum5o-0eDAgKI54VBPUAJomIFM/pubhtml" ;
console.log(recruitment);
var tabletop = sheet.init({
key: '1M7glQxJb31B3lQyKNqum5o-0eDAgKI54VBPUAJomIFM',
callback: showInfo
})
</script>
I've tried various combinations of
import 'tabletop'
Tabletop.init(...)
-or-
require('tabletop')
import as from 'tabletop'
I've tried various relative pathways
'tabletop'
'./tabletop'
'../../tabletop'
'../../node_modules/tabletop'
without no avail all with either a require or an import or a HEAD inserted sript tag
without a path I get
vue.runtime.esm.js?4bfb:619 [Vue warn]: Failed to resolve async component: function () {
return Promise.all(/*! import() */[__webpack_require__.e(20), __webpack_require__.e(29)]).then(__webpack_require__.bind(null, /*! ./src/.vuepress/components/joblist */ "./src/.vuepress/components/joblist.vue"));
}
Reason: ReferenceError: Tabletop is not defined
with a relative path I get ...
client?cae4:159 ./src/.vuepress/components/joblist.vue?vue&type=script&lang=js& (./node_modules/cache-loader/dist/cjs.js??ref--3-0!/usr/local/lib/node_modules/vuepress/node_modules/babel-loader/lib??ref--3-1!./node_modules/cache-loader/dist/cjs.js??ref--0-0!/usr/local/lib/node_modules/vuepress/node_modules/vue-loader/lib??vue-loader-options!./src/.vuepress/components/joblist.vue?vue&type=script&lang=js&)
Module not found: Error: Can't resolve '../../tabletop' in '/home/pi/GitHub/starlife-website/src/.vuepress/components'
errors # client?cae4:159
(anonymous) # socket.js?e29c:47
sock.onmessage # SockJSClient.js?0a33:58
EventTarget.dispatchEvent # sockjs.js?fb87:170
(anonymous) # sockjs.js?fb87:887
SockJS._transportMessage # sockjs.js?fb87:885
EventEmitter.emit # sockjs.js?fb87:86
WebSocketTransport.ws.onmessage # sockjs.js?fb87:2961
vue.runtime.esm.js?4bfb:619 [Vue warn]: Failed to resolve async component: function () {
return __webpack_require__.e(/*! import() */ 20).then(__webpack_require__.bind(null, /*! ./src/.vuepress/components/joblist */ "./src/.vuepress/components/joblist.vue"));
}
Reason: Error: Cannot find module '../../tabletop'
Every variation of the path both for import or require seems to end up in the same two errors:
Error: Cannot find module '../../tabletop'
-or-
Reason: ReferenceError: Tabletop is not defined
After several hours I'm lost ... spent hours googling for examples none of which are based within vuepress and none have been helpful
With Insuffiicent knowledge to poke through webpack, and running out of alternatives my project has hit a wall and I cannot see my way around.
Any ideas are much appreciated
Current state of project can be found at
https://github.com/kingdom-values-clients/starlife-website/tree/345d55eed65f110626a9e4d3bcadae1efcca0cbc
See above and also in thes commit
https://github.com/kingdom-values-clients/starlife-website/tree/345d55eed65f110626a9e4d3bcadae1efcca0cbc
Error: Cannot find module '../../tabletop'
-or-
Reason: ReferenceError: Tabletop is not defined
I know I'm probably doing something dumb here but cannot figure it out nor can I find any help for anything remotely like this inside a vuepress component.
I've been using Webpack for my ES6 JS project and has been going well until I started to play with dynamic imports.
What I had that worked (router.js):
import { navigo } from "Navigo"; // router
import { clients } from "Controllers/clients.js";
const navigo = new Navigo();
navigo_router.on({
'/clients': () => {
clients.init();
}
});
But the more pages/routes I add, the more imports get stacked up in the head of the module. This is a relatively large app and I have a lot of pages/routes to add and therefore I need to load them dynamically to reduce the size of the initial page load.
So, following Webpack's documentation for dynamic imports, I tried the following which loads the controller module only when the relative route is called:
import { navigo } from "Navigo"; // router
const navigo = new Navigo();
navigo_router.on({
'/clients': () => {
import("Controllers/clients.js").then((clients) => {
clients.init();
});
}
});
But saving this in my editor resulted in a Babel transpiling error; SyntaxError: 'import' and 'export' may only appear at the top level, and clients.init() is not being called when tested in browser.
After a bit of reading, I discovered I needed a Babel plugin to transpile dynamic import() to require.ensure. So, I installed the plugin using the following command:
npm install babel-plugin-dynamic-import-webpack --save-dev
And declared the plugin in my babel.rc file
{ "plugins": ["dynamic-import-webpack"] }
After installing the plugin, the transpiling error disappeared and checking my transpiled code I found that the dynamic import()s has in fact been changed to require.ensure as expected. But now I get the following browser errors when testing:
Error: Loading chunk 0 failed.
Stack trace:
u#https://<mydomain.com>/js/app.bundle.js:1:871
SyntaxError: expected expression, got '<' 0.app.bundle.js:1
Error: Loading chunk 0 failed.
I didn't understand why it was referencing 0.app.bundle.js with the 0. prefix, so I checked my output/dist folder and I now have a new file in there called 0.app.bundle.js:
0.app.bundle.js 1,962bytes
app.bundle.js 110,656bytes
I imagine this new bundled file is the dynamically imported module, clients.js.
I only added dynamic importing to that one route and have left all the other routes as they were. So, during testing, I can view all routes except that one /clients route that now throws the above errors.
I'm totally lost at this point and hoped somebody could help push me over the finish line. What is this new file 0.app.bundle.js and how am I supposed to be using it/including it in my application?
I hope I've explained myself clearly enough and look forward to any responses.
I managed to fix my own problem in the end, so I will share what I discovered in an answer.
The reason the chunk file wasn't loading was because Webpack was looking in the wrong directory for it. I noticed in the Network tab of my developer console that the the chunk file/module was being called from my root directory / and not in /js directory where it belongs.
As per Webpack's documentation, I added the following to my Webpack config file:
output: {
path: path.resolve(__dirname, 'dist/js'),
publicPath: "/js/", //<---------------- added this
filename: 'app.bundle.js'
},
From what I understand, path is for Webpack's static modules and publicPath is for dynamic modules.
This made the chunk load correctly but I also had further issues to deal with, as client.init() wasn't being called and yielded the following error:
TypeError: e.init is not a function
To fix this, I also had to change:
import("Controllers/clients.js").then((clients) => {
clients.init();
});
To:
import("Controllers/clients.js").then(({clients}) => {
clients.init();
});
Note the curly braces in the arrow function parameter.
I hope this helps somebody else.
For debugging, you need to do
import("Controllers/clients.js").then((clients) => {
console.log(clients);
});
maybe working
import("Controllers/clients.js").then((clients) => {
clients.default.init();
});
This project has to rely on older version of a SAP system. As a result some of the latest features do not work. I would like to have the "minutesStep" property of the latest "TimePicker" version, so I went to the source code and copied the latest TimePicker controls code to our old project.
I am having issues as "TimePicker" relies on the new version of "TimePickersliders" as well. I need to copy its source code as well. However I fail to make the "TimePicker" use the new "TimePickerslider" source code which I copied to the project as well.
sap.ui.define(['jquery.sap.global',
'sap/m/InputBase',
'sap/m/MaskInput',
'sap/m/MaskInputRule',
'sap/m/ResponsivePopover',
'sap/ui/core/EnabledPropagator',
'sap/ui/core/IconPool',
'sap/ui/model/type/Time',
'./TimePickerSliders'], // Here is the problem.
function(jQuery, InputBase, MaskInput, MaskInputRule, ResponsivePopover, EnabledPropagator, IconPool, TimeModel, TimePickerSliders) {
What should be the './TimePickerSliders' path, so that it includes the file in my project? Its in the same folder, but it just fails to pick it up.
Here is the Error I get:
Uncaught (in promise) Error: failed to load 'PROJECT_NAME/controls/MyTimePicker.js' from ./controls/MyTimePicker.js: Error: failed to load 'PROJECT_NAME/controls/Slider.js' from ./controls/Sliders.js: Error: failed to load 'PROJECT_NAME/controls/VisibleItem.js' from ./controls/VisibleItem.js: Error: failed to load 'PROJECT_NAME/controls/library.js' from ./controls/library.js: 404 - NOT FOUND
Is this even possible, reasonable or legal? I seem to be missing some other files as well.
If TimePickerSliders is a .js file located in your controls folder (I assume its on the same level as view and controller folders), try to call it like follows:
sap.ui.define([
...
'<project-namespace>/controls/TimePickerSliders'],
function(jQuery, InputBase, MaskInput, MaskInputRule, ResponsivePopover, EnabledPropagator, IconPool, TimeModel, TimePickerSliders) {
I am trying to set up angular 2 according the quickstart found at http://angular.io. I have copied every file exactly as described in the guide, but when I run npm start and a browser tab opens, I get the "Loading..." with the following error in the console:
Uncaught SyntaxError: Unexpected token < (program):1
__exec # system.src.js:1374
Uncaught SyntaxError: Unexpected token < angular2-polyfills.js:138
Evaluating http://localhost:3000/app/boot
Error loading http://localhost:3000/app/boot
This is my app.component.ts:
import {Component} from 'angular2/core';
#Component({
selector: 'my-app',
template: `<h1>My First Angular 2 App</h1>`
})
export class AppComponent {
}
My boot.ts:
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
bootstrap(AppComponent);
My index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Angular 2 Quick Start</title>
<script src="node_modules/es6-shim/es6-shim.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script>
System.config({
packages: {
format: 'register',
defaultExtension: 'js'
}
});
System.import('app/boot')
.then(null, console.error.bind(console));
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
My package.json:
{
"name": "angular2-quickstart",
"version": "0.1.0",
"scripts": {
"tsc": "tsc",
"tsc:w": "tsc -w",
"lite": "lite-server",
"start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
},
"license": "MIT",
"dependencies": {
"angular2": "2.0.0-beta.0",
"systemjs": "0.19.6",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.3",
"reflect-metadata": "0.1.2",
"rxjs": "5.0.0-beta.0",
"zone.js": "0.5.10"
},
"devDependencies": {
"concurrently": "^1.0.0",
"lite-server": "^1.3.1",
"typescript": "^1.7.3"
}
}
And finally my tsconfig.json:
{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules"
]
}
Try replacing this
System.config({
packages: {
format: 'register',
defaultExtension: 'js'
}
});
with this
System.config({
packages: {
app: { // must match your folder name
format: 'register',
defaultExtension: 'js'
}
}
});
I was trying to apply a slightly different folder structure to their quickstart and ran into the same issue. I found that the name of the property on the "packages" object had to match the parent folder.
A tip for those who encounter the "Unexpected token <" error. For me, this happened when SystemJS attempted to retrieve a dependency (JavaScript file) and instead the web server returned an HTML page (hence the unexpected opening < in the html).
I was able to pinpoint this in Chrome's Dev Tools on the Network tab by looking through the downloaded JavaScript files one-by-one until I found the one where HTML was returned instead. This made it easy to resolve the issue with my import.
Hoping we may get a more meaningful error message at some point-
I've had similar issues with different node modules and came here from Google.
Usually, I would get the error after importing a package and then attempting to use it.
For example, I had the same issue when loading https://github.com/ngrx/store.
I checked my network tab and it turns out the file that was loaded for store.js (that module's main file) was not correct. It requested store.js, but got my index.html, which started with <!DOCTYPE html>, i.e. it started with a "<", which is not valid JavaScript.
It is not clear to me why my index.html was served in lieu of the actual JavaScript file. One explanation could be that SystemJS made a request that led nowhere and my server was configured to serve index.html as a default. I don't have enough data to prove this, though. Cum grano salis.
In any case, I fixed it by explicitly telling SystemJS where a package lives if it can't find it on its own. So, for example, to fix a failing import { Store } from '#ngrx/store';, you can do:
System.config({
packages: {
src: {
format: 'register',
defaultExtension: 'js'
}
},
map: { '#ngrx/store' : '/node_modules/#ngrx/store/dist/store.js' } // <-- this!
});
System.import('src/boot')
.then(null, console.error.bind(console));
Because the Store module lives in that file. This way, SystemJS finds it, and the module can be imported just fine.
I had a similar issue importing rx.js
I ended up solving it by adding a path to the System.config()
System.config({
defaultJSExtensions: true,
paths: {
'rx' : 'lib/rx.js'
}
});
I had a similar issue, I had configured the IIS server to rewrite all paths to index.html in order to get the router working properly. (Page refresh was returning 404. Read details in this answer)
As user #dchacke points out, it's because System.js expects a .js file not a .html file. This indeed produces the strange message starting with SyntaxError: Unexpected token <. Temporarely disabling the URL rewriting allows me to see the real issue.
When importing child components into parent components System.js can get confused if paths are not declared properly.
For example parent.component.ts has the following import:
import { ChildComponent } from './childComponentFolder/childComponent';
Throws this error:
GET app/parentComponentFolder/childComponentFolder/childComponent.js 404 (Not Found)
Error: Error: XHR error (404 Not Found) loading app/parentComponentFolder/childComponentFolder/childComponent.js
Changing the import instruction path from relative to absolute path solves the issue:
import { ChildComponent } from 'app/childComponentFolder/childComponent';
Mapping the path in system.config.js could also do the trick, but I find it harder to maintain because it's not readily apparent why the import path works or not. Now I can uncomment the rewrite rules in Web.config and all works just fine.
Edit:
It seems that typescript transpiler is very picky about paths. Only relative paths pass without throwing errors:
Basically you need to step back up one folder from parentComponentFolder/ to app/ folder.
import { ChildComponent } from '../childComponentFolder/childComponent';
I ran into this same problem. I fixed it by implementing the following in my index.html (note: I put the angular2 js dependencies in 'lib' folder):
<html>
<head>
<title>Desktop main</title>
</head>
<body>
<div>
<my-app>Loading...</my-app>
</div>
<script src="~/lib/anguar2/angular2-polyfills.js"></script>
<script src="~/lib/es6-shim/es6-shim.js"></script>
<script src="~/lib/systemjs/system.src.js"></script>
<script>
System.config({
defaultJSExtensions: true
});
</script>
<script src="~/lib/rxjs/rx.js"></script>
<script src="~/lib/anguar2/angular2.dev.js"></script>
<script>
System.import('app/boot');
</script>
</body>
</html>
app.component.ts looks like this:
import {Component} from "angular2/core";
#Component({
selector: "my-app",
template: "<h1>Hello Angular 2</h1>"
})
export class AppDesktopComponent {
}
Wish I could tell you why this works and the angular2 quickstart boilerplate doesn't.
I was getting a similar problem:
Unexpected token ]
When starting the server. Turns out I had a trailing comma in my tsconfig.json:
...
"files": [
"app.ts",
"typings.d.ts",
"abc-vt/abc-vt", <-Doh!
]
Lesson: Don't just assume it's an error in your source code -- check your config files as well.
In my case, I'd inadvertently included the file extension on the import...
import {SomeComponent} from 'some.component.ts';
And (obviously!) it should have been...
import {SomeComponent} from 'some.component';
A trailing comma in your systemjs configuration will cause this.
Check the systemjs.config.ts file and make sure the json is valid.
I had a similar bug. I got:
Uncaught SyntaxError: Unexpected token = (index):16
because I tossed a semicolon at the end of the #Input() in the hero-detail.component file.
Hope this helps somebody.
The primary cause of this issue is that the file you are trying to import is an html file, not a js file. You can see this by using the network tab in Chrome to have a look at the file it actually imported.
My issue wasn't solved by the methods above. For me, this happened because I had routed all default routes through to the index.html page, which is how I get Angular deep linking working in Visual Studio Enterprise. When I requested a file without the extension, and it couldn't find that file, it would serve the default index.html page, which would start with a < character, and fail.
The giveaway for me was that when I put the full path to the exact file, it would work.
Anyhow, to fix this, I had to add an Ignore route for the node_modules folder in my RouteConfig.cs file:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("node_modules/{*pathInfo}");
}
I had received the same error message.
Similar to what other people mentioned, my case was caused by url rewrites, serving the html instead of the javascript expected by angular.
I am using lite-server/browser-sync to develop and host my app locally. To get the angular routing working properly, I was using
var history = require('connect-history-api-fallback')
to redirect relevant pushState navigation back to index.html. Ultimately, a misconfiguration in my typescript imports led to one request not being recognised as a js file and instead redirected to index.html. The difficulty was how to figure it out.
I found that you can enable verbose logging for the connect-history-api-fallback.
middleware: [history({
index: '/src/index.html',
verbose: true
})]
which then led me to find the culprit by scanning the log for redirected entries:
Not rewriting GET /node_modules/systemjs/dist/system.js because the path includes a dot (.) character.
Not rewriting GET /node_modules/core-js/client/shim.min.js because the path includes a dot (.) character.
Rewriting GET /src/culprit to /src/index.html
For those who read the whole thing and didn't found anything interesting, I may have another option for you.
I ran into the same problem because the website was deployed on more than 1 web server. The problem was related to different builds deployed on some servers.
Basically, you have 1 server with one version and another server with some other version. So, of course when you load balance you're likely to get 404 on some resources on some servers because the versions are different (remember the main.xxxxx.js where xxx is different at every build). And if you configured your webserver to return a 404 webpage
- which happens a lot I guess - you get some HTML instead of the JS files then the unexpected token.
So, check your versions on each server !
For me, this error was caused because I served my angular frontend with a simple node express server as such:
app.use('/*', (req, res) => {
res.sendFile(path.join(__dirname,'index.html'));
});
but I had forgotten to specify that all static files should be served from the current directory with the line:
app.use(express.static(__dirname));
So every call for a static asset returned index.html. Woops. Once I added that line, everything was fine. Hope this can help someone down the line :)
I was following along to this post by Rebecca Murphey: http://blog.rebeccamurphey.com/scaffolding-a-buildable-dojo-application
I was substituting her file structure with my own.
Running the normal version of the scripts works fine, but the moment I compile them using the build tool, the script errors.
It's very likely a small problem with how the files are referenced via my Profile.js script but maybe someone here can help me get the settings correct before running the build tool so the compiled files will work as they should.
My file structure is as follows...
/www
/Assets
/Scripts
/Classes
build.sh
Init.js
Load.js
Profile.js
/Dojo
Dojo.js
/dojo-sdk
index.html
My index.html file has the following code...
<script>
var djConfig = {
modulePaths : {
'Integralist' : '../Classes'
}
};
</script>
<script src="Assets/Scripts/Dojo/Dojo.js"></script>
<script>
dojo.require('Integralist.Init');
</script>
...and the Init.js file has the following code...
dojo.provide('Integralist.Init');
dojo.require('Integralist.Load');
dojo.declare('MyApp', null, {
constructor: function(config) {
this.version = config.version || '1.0';
this.author = config.author || 'Unknown';
}
});
var myapp = new MyApp({
author: 'Mark McDonnell'
});
alert(myapp.author);
alert(myapp.version);
...lastly, the Load.js file has nothing in it but this...
dojo.provide('Integralist.Load');
alert('I\'m the Load.js file');
...and this all runs fine. When I load index.html I get 3 alert messages, brilliant.
The problem occurs when I try to run the build tool.
Via Mac OSX i locate the /Classes/ directory and run 'sh build.sh' and the build.sh file within the /Classes/ directory consists of the following code...
cd ../../../dojo-sdk/util/buildscripts
./build.sh profileFile=../../../Assets/Scripts/Classes/Profile.js releaseDir=../../../Assets/Scripts/Release
...now, after running the build tool I have a new /Release/ directory created within my /Scripts/ directory, this /Release/ directory consists of...
/www
/Assets
/Scripts
/Release
/Integralist
/Classes
Init.js
Init.js.uncompressed.js
/dojo
--loads of dojo related files--
...I then created a separate index file called index-release-version.html and changed the script code as suggested by the article, so it looks like this...
<script src="Assets/Scripts/Release/Integralist/dojo/dojo.js"></script>
<script>
dojo.require('Integralist.Init');
</script>
...from here I get the following error...
Failed to load resource: the server responded with a status of 404 (Not Found)
Uncaught Error: Could not load 'Integralist.Init'; last tried '../Integralist/Init.js'
...and just for reference my Profile.js file that is used by the build tool consists of the following (and it's here I think the problem may be)...
dependencies = {
stripConsole : 'all',
action : 'clean,release',
optimize : 'shrinksafe',
releaseName : 'Integralist',
localeList : 'en-gb',
layers: [
{
name: "../Classes/Init.js",
resourceName : "Integralist.Init",
dependencies: [
"Integralist.Init"
]
}
],
prefixes: [
[ "Integralist", "../Classes" ]
]
}
Any help really appreciated as I desperately want to get my head around how Dojo works :-)
Thanks!
M.
I'd suggest working from the repo I linked to from my blog post (http://github.com/rmurphey/dojo-scaffold) -- I double-checked that it's definitely working :) -- and make changes to it until your changes break something, rather than trying to create your own structure right off the bat.
At a glance, I'm not 100% clear why you've got a Dojo.js file inside your directory structure, (is this the base Dojo lib or something else?), but the rest of Dojo is located elsewhere. If you use the structure I proposed, you can safely remove the djConfig declaration when using the built files, but as Dan mentioned, you may need to keep it if you're using a different configuration.
Do you have that djConfig variable in your index-release-version.html? It looks like Dojo is trying to find init.js at ../Integralist/Init.js, but you somehow need to tell it to look in ../Classes/Init.js
This is what your modulePaths : {'Integralist' : '../Classes'} was doing in your Index.html