./xxx.scss. Required module not found - flowtype

I am having trouble with scss module imports when I am running flow check. I have tried out various approaches including
.flowconfig
[options]
module.name_mapper.extension='scss' -> '<PROJECT_ROOT>/flow-typed/stub/css-module.js'
and I have
// #flow
type CSSModule = { [key: string]: string }
const emptyCSSModule: CSSModule = {}
export default emptyCSSModule
in the css-module.js. Do you know why it's happening?

I believe I had a similar issue when trying to use .styl files for stylus.
You might be able to solve this issue by doing the following which had worked for me:
Remove the css-module.js file.
Remove that module.name_mapper.extension line that you have in your .flowconfig
Add the following to the [options] in your .flowconfig:
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json
module.file_ext=.scss

Related

Vue CLI with electron - Unexpected character (1:0) when using native modules

In some popular NodeJS libraries, e.g. ssh2 or node-pty, there is natively compiled code as part of the library.
Creating the project with
vue create my-project
vue add electron-builder
yarn add ssh2
then importing and using ssh2's Client in the background process results in following errors during
electron:build
ERROR Failed to compile with 1 errors 5:29:10 PM
error in ./node_modules/cpu-features/build/Release/cpufeatures.node
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
# ./node_modules/cpu-features/lib/index.js 1:16-60
# ./node_modules/ssh2/lib/protocol/constants.js
# ./node_modules/ssh2/lib/client.js
# ./node_modules/ssh2/lib/index.js
...
This error occurs with many other libs or transitive dependencies and the reason for it is absence of native-ext-loader on Webpack chain. I understand why it is not included by default, and I would like to see what is the best way to add it.
One solution I found is this:
Add yarn add -D native-ext-loader (my version is 2.3.0 and electron is at 13.x)
Adjust vue.config.js and add the chainWebpackMainProcess like this:
const path = require('path')
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
// options placed here will be merged with default
mac: {
target: 'dmg',
icon: 'build/icon.icns',
asar: true
}
},
preload: 'src/preload.ts',
chainWebpackMainProcess(config) {
config.module
.rule("node")
.test(/\.node$/)
.use("native-ext-loader")
.loader("native-ext-loader")
.options(
process.env.NODE_ENV === "development"
? {
rewritePath: path.resolve(__dirname, "native"),
}
: {}
)
}
}
}
}
Both, electron:build and electron:serve are now working and ssh2 client is happily delivering the stdout to renderer via ipcMain. Not sure it is the most elegant way of solving it, though.

How to use fully functioning JsonPath in angular 2+?

I followed https://www.npmjs.com/package/jsonpath. Tried a way to include external js file, but no luck.
import jsonPath worked after -
import * as jsonPath from 'jsonpath/jsonpath';
JsonPath plush also worked JSONPath-plus which is same as of Jsonpath. I have following coding snippet which is working for me-
install JSONPath-plus
npm install jsonpath-plus
angular.json file
"scripts": [
"node_modules/jsonpath-plus/dist/index-umd.js",
"src/assets/js/jsonpath.js"
]
jsonpath.js have following code -
function jsonPath() {
return JSONPath;
}
Now use this function in ts file with declaring it like below -
declare const jsonPath: any;
// use it like
jsonPath().JSONPath(path, json);

Recompile after imported file changed in meteor app

I'm creating babel plugin to manage import paths according to some conditions based on file existence. On initial build everything works fine, but when I add or remove file that would impact result of the conditions, compiler doesn't recompile file that is importing changed file, therefore conditions are still resolved as if referenced file existed, but compiler is not able to find it.
I believe this is due to cache. So how can I manage/clear cache? Of course I would like to keep as much cacheing as possible. So, maybe, is there way to programmatically remove from cache only files that were impacted by my plugin?
Basically logic of plugin is as follows:
const fs = require("fs");
const fs_path = require("path");
function shouldResoulveImport(node) {
/* some checks, returns bool */
}
module.exports = function(babel) {
return {
visitor: {
ImportDeclaration(path, state) {
if (!shouldResoulveImport(path.node)) {
return;
}
const existing_file = /* some checking for another file existence */;
if (existing_file) {
path.node.source.value = existing_file;
}
}
}
};
};
What i try to achieve is to use some default file for import, but when same file in other particular directory exists then change the import for the other file.
I use meteor 1.7 with babel 7 beta and react.
I've checked with babel support and it seems to be issue of meteor.
Thanks.
There was no way to achieving it in this manner.
So I decided to use try on import overriding file and exporting it further. And if the import fails, it means, that file doesn't exists so default file export its default content:
...
let toExport;
try {
import Overrides from "overriding_path";
toExport = Overrides;
} catch (e) {
toExport = OriginalExport;
}
export default toExport;
Later just build plugin that instead of modifying import modifies file.

Angular 2.0 - Meteor UploadFS Error

I am working on the Angular 2.0-Meteor tutorial and on step 20 "Handling Files with CollectionFS" I am getting an error.
"Cannot find module 'meteor/jalik:ufs'." I have tried removing and adding jalik:ufs and calling meteor reset but this error seems to persist.
I get the error when trying to run the sample code included before Step 21 as well.
It is related with typings. Right now I don't think there is an existing typings for this package.
So you can write your own typings.
Or use the temporary way to remove the warning:
Remove import { UploadFS } from 'meteor/jalik:ufs';. Then add declare const UploadFS: any; in any file.
Tutorial was updated in between:
See Point 21.22 Declare meteor/jalik:
Link
declare module "meteor/jalik:ufs" {
interface Uploader {
start: () => void;
}
interface UploadFS {
Uploader: (options: any) => Uploader;
}
export var UploadFS;
}

Using modules in Meteor.js with Typescript

Folks, I'm trying to do something that I thought ought to be simple, but I must be doing something wrong. I'm trying to simply have a clear structure in my meteor application which uses Typescript.
Here are my requirements:
All interfaces are available in both client and server
Some class implementations are only available on the server
I don't want to rely on file load order for my application to work properly
I need my own module to not clash with global objects (such as the Position class for example)
I need to have one monolithic include file for server, one for both client and server and one for client (don't want to have 10s of includes on top of my files)
The setup that I have right now is this
server
server-book.ts
client
shared
collections.ts
definitions
server
include.d.ts (includes all .d.ts files in this folder)
server-book.d.ts (server specific implementation of book)
client
shared
include.d.ts (includes all .d.ts files here)
book.d.ts (book interface definition)
collections.d.ts
In each .d.ts file I have
module MyModule {
interface Bla {}
};
In each .ts file that defines a class I have:
module MyModule {
export class MyBla implements Bla {};
}
All .d.ts files generated for classes are generated by tsc -d.
No .ts files are being included via ///<reference> rather only .d.ts files.
Now, when I run this, I get an error that MyModule is undefined:
/// <reference path="shared/include.d.ts"/>
/// <reference path="server/include.d.ts"/>
Meteor.startup(() => {
var temp = new MyModule.ServerBook();
});
The error occurs right on MyModule.
What am I doing wrong? What should be the proper setup here?
Thanks!
I have dealt with this issue on my blog. I decided to use the evil eval command, since it gave me the easiest possibility of using modules till something more sophisticated appears.
File /lib/foo.ts is position in the subdirectory since it has to be loaded before Bar.
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Foo {
foo():string {
return 'foo'
}
}
}
File /bar.ts
/// <reference path="lib/foo.ts"/>
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Bar extends Foo {
bar () : string {
return 'bar';
}
}
}
File /test.ts
/// <reference path="lib/foo.ts"/>
/// <reference path="bar.ts"/>
var m = new Hugo.Bar();
console.log(m.bar());
console.log(m.foo());
As mentioned here, for classes, the solution is even simpler:
class ExportedClass {
variable : int;
}
this.ExportedClass = ExportedClass;
Definition files should use the declare keyword. You would normally get an error if you didn't use this keyword.
declare module MyModule {
export interface Bla {}
}
And
declare module MyModule {
export class MyBla implements Bla {
}
}
It is also worth checking that the ServerBook class has the export keyword (just like MyBla in your examples).
After lot of trial and errors, here are my findings so far :
Using typescript "module" keyword doesn't get well with Meteor. I think at the moment you cannot use it (or the workarounds are too complicated for me).
However, here is what you can do :
Let say that you have package A where you want to define a class ClassToExport which you want to make public.
class ClassToExport {
getFoo(){
return "foo";
}
}
Please note that you can't write this.ClassToExport = ClassToExport and
api.export('ClassToExport') or else ClassToExport won't be available in the global scope of package A, hence the need for a module/namespace for exporting your class, which we will see next.
Now, for the class to be available for the consumers of your package, you have to create a namespace, which will be the equivalent of the "module" typescript keyword for internal module.
So let's write :
declare var packageA; //so that the compiler doesn't complain about undeclared var
packageA = packageA || {}; //so that this namespace can be reused for the entire package
packageA.ClassToExport = ClassToExport; //the actual export
Now, don't forget to write
api.export('packageA') in the package.js of package A
If you have a package B where you want to use ClassToExport, you write in package B:
var cte = new packageA.ClassToExport();
without forgetting to api.use package A in package B's package.js
If you don't want to write the namespace each time you use the class, you can also write var ClassToExport = packageA.ClassToExport; at the top of your using file.
If you need a global class for you package only, without exporting it, then you can do instead just :
this.ClassToExport = ClassToExport
and again don't write api.export('ClassToExport'), or it won't be available in the package anymore.
This way, i think the features (export/ import) of internal typescript modules are there.
If you are not afraid of gulp build, I have prepared a typescript boilerplate project which allows you to comfortably use typescript from within your app, not depending on packages.
https://github.com/tomitrescak/meteor-boilerplate-typescript
Random idea, what about extend Meteor instead of Window.
Meteor.yournamespace = Meteor.yournamespace || {};
Meteor.yournamespace.myclass = new MyClass();
or
Meteor.yournamespace.MyClass = MyClass();
I think this is less invasive than go directly to the window object IMHO. my two cents.
now you can do Meteor.yournamespace.MyClass :P
--EDIT
Then you could create a meteor-extend.d.ts file and do something like:
/// <reference path="main.d.ts" />
declare module Meteor {
var yournamespace: any;
}
Now you can remove the <any> before Meteor and Typescript will not complaint.

Resources