Should I compile my react hook library, or publish only the ES6 code? - react-hooks

I have a very simple hook that I want to publish to npm, and I'm struggling to see why I should compile my hook at all. Let me first provide some context.
My hook depends only upon React.useState and React.useEffect. The purpose of this hook is to be used with my existing library: https://npmjs.com/package/simple-shared-state. As you can see, there's very little to this hook:
import { useEffect, useState } from "react";
export default (store, selectors) => {
const [state, setState] = useState([]);
useEffect(() => {
const unwatch = store.watchBatch(selectors, (array) => {
setState(array.slice());
});
return unwatch;
}, []);
return state;
};
I've looked at the create-react-hook cli tool, and tried it out, but I don't see how the included dev-dependencies are needed for my project. My hook is already usable in my mono-repo, where I added a folder, react-test-ground/, in which I provide a working app that I bootstrapped using CRA.
Concerning Testing:
If it makes sense to do, I can go the extra step of adding unit tests specifically for this hook, but at the moment, I can't see a strong need for this since the core of the functionality is in simple-shared-state, and all of that logic is already covered with pretty extensive tests.
I had a look at react-hooks-testing-library, and based on the "When to use this library" and "When not to use this library", it seems to me that my situation is one where I don't need to use this library. I think my hook is simple enough that the extra steps of adding more tests are hard to justify. Do you agree? Can you think of a reason why I should use react-hooks-testing-library?
Concerning compilation:
I can't see a strong reason to compile and minify my hook, since react app developers will almost exclusively be compiling their project from JSX anyway.
Summary
Given all of the above, is there any reason to do anything more than simply publish my hook, exactly as shown, on npm? Meaning, the package.json would include "main": "src/index.js", and no dist/ directory. React would go in the package.json under peerDependencies, and that's it. App developers would simply compile the source ES6 code of this hook into their bundle, and that's all.
Thanks in advance for taking the time to read and reply!

You can publish ES6 code.
The current js spec is ES2020. All runtimes should support all features from this spec.
Thus you need compile own code to latest standard. If user want to use your code on older runtimes(e.g. IE11) he can transpile all code in his build process.

Related

Webpack Autoreload for Unimported Files

I am working with WebAssmbly and Webpack together. My source wasm language is Go. How it works is that there is a webpack load rule that builds and imports the file to my project:
// index.js
import wasm from './main.go'
...
// webpack.config.js
...
rules: [
{
test: /\.go/,
use: ["golang-wasm-async-loader2"],
},
]
...
With watch mode enable, this works absolutely wonderfully for my main.go file. The issue arises when I change any other file. Go compiles all the files in a particular module to a single binary, so I only need to import the main file, and importing other files would just cause it to run multiple times (which I also don't want).
I was wondering if it was possible to force webpack to reload regardless of a file being imported or not?
I looked over at their watch docs however I did not find anything :(.
Thanks :)
Unfortunately, it sees seems that this is impossible to fix from webpack's user api. The only way to fix this is to change how the loader works.
Using The loader API, it is possible to add a context dependency or a generic dependency so that those files are watched for reloads as well :)

How to create a Qt-Quick Test

I have to create a Unit-Test.
But first, I´ve to get clear what to do.
There is a QtQuick2-App written and now I would like to do Unit-Tests with the GUI. What are the steps for Unit-Tests with GUI? After reading the Qt-documents, I could not create any ideas for starting with the test.
Hope somebody can help me.
Edit: I was able to run some tests, after adding tst_button.qml and tst_test.cpp to my Project (main.cpp is in comments now). Is this the right way, or should I create a new project just for the Tests? If yes, what kind of project is needed?
And the last question: Do I need to build up my MainForm for pressing buttons for example?
tst_button.qml
import QtQuick 2.4
import QtTest 1.0
Rectangle{
id: myRec
property var myMainForm: null
TestCase{
name:"ButtonClick"
when:windowShown
function test_init(){
var createMyWindow = "import QtQuick 2.0; MainForm{id:myForm}"
var myMainForm = Qt.createQmlObject(createMyWindow,myRec)
myRec.myMainForm = myMainForm
}
}
}
tst_test.cpp
#include <QtQuickTest/quicktest.h>
QUICK_TEST_MAIN(test)
Testing and Debugging lists two ways:
Qt Test (also known as testlib) - a framework for unit tests of C++ code
Qt Quick Test - a framework for unit tests of QML code
You can use Qt Test for testing Qt Quick applications, but that's generally better for when you need access to C++ API that isn't available in QML.
Do I just add a *.qml file to my project and fill it with my code? If yes, what do I have to do to start the test?
You'll first need to make the tests a separate project, unless you're planning on using qmltestrunner (I have no idea why that tool isn't documented by Qt itself).
The Running Tests section of Qt Quick Test's documentation details how to get a test up and running.
I was able to run some tests, after adding tst_button.qml and tst_test.cpp to my Project (main.cpp is in comments now). Is this the right way, or should I create a new project just for the Tests?
If your application is pure QML and only intended to be run with qmlscene, for example, then doing it that way is fine. However, if you intend to deploy/ship your application, you'll probably need to have an executable, which means making separate projects for the application and the tests.
If yes, what kind of project is needed?
You could have a SUBDIRS project, so that your tests and the application itself can all be opened at once in Qt Creator. Something like this:
myapp.pro
app/
main.cpp
app.pro
resources.qrc
main.qml
tests/
tests.pro
data/
tst_stuff.qml
And the last question: Do I need to build up my MainForm for pressing buttons for example?
No. The .ui feature is just a format that allows Qt Creator to enforce certain constraints to make it easier to design Qt Quick UIs with Qt Quick Designer. MainForm.ui.qml is therefore just a convenience. If you already have an existing component in QML, you can create instances of that and test it.

What is the modularization story for TypeScript in the browser?

I am new to browser development, so I have no prior experience with AMD, CommonJS, UMD, Browserify, RequireJS, etc. I have been reading a lot about them and I believe I generally understand the JavaScript story but I am still very confused as to how to make everything work together.
I have a library written in TypeScript. It is a pure TypeScript library, it doesn't interact with a browser or any browser framework nor any node or NPM things.
I also have a TypeScript client application that leverages this library. The client application may leverages a web framework as well (e.g., jQuery).
Now when I compile my two TypeScript files (which we will assume are in separate projects, isolated from each other and built separately), each will generate a .js file. In Visual Studio I have to choose AMD or Common as my module loader.
This is where things fall apart. My research tells me that if I want to work on the web I either need to use Browserify or RequireJS. Browserify appears to require I first install Node on my machine and then use a command line tool as a post-build step to generate a file and as far as I can tell this isn't available as a NuGet package. Alternatively, I can use RequireJS but then all of the examples stop working. Something about not doing things on window load and instead doing them somewhere else, but nothing that I have found really explains that well.
So, what is the story here? I want to use TypeScript but at the moment it really feels like it is just a language, there aren't any compelling usage stories available to me as a developer as I have grown accustomed to in the Microsoft ecosystem.
TypeScript does support AMD and CommonJS just as JavaScript. But in addition it also supports internal modules. When using internal modules in conjunction with a decent build system like gulp-typescript you'll find that internal modules can cover lot of use cases where one would choose AMD/CommonJS in traditional JavaScript projects.
TypeScript gives you the freedom to decide yourself. If you need asynchronous module loading you are free to use AMD via external modules. You can also use CommonJS and/or use browserify to link together your code into a single file.
I've found that when you are a library developer - that is you ship your TypeScript compiled JS code to other developers - internal modules are a good compromise. You don't force your target audience (developers) to use any special module system like AMD/CommonJS, but instead ship isomorphic JS that runs in the browser as well as in node. Yet you still have a way of modularizing your code internally, just as AMD/CommonJS would allow you.
TL;DR: When you use TypeScript you get internal modules for free, and they provide you with a flexibility that would else only be achieved by AMD/CommonJS. Yet external modules still have their advantages. In the end, you should decide what is the best fit for your project.
TypeScript is a superset of JavaScript so its story is the story of JS, not of .NET or any other Microsoft product.
If you compile your TypeScript modules to AMD, then you load them through an AMD module loader like RequireJS (or Dojo, or curl) in your entrypoint HTML file, which can be as simple as this (using RequireJS):
<!DOCTYPE html>
<title>Application name</title>
<script src="scripts/require.js" data-main="scripts/client"></script>
(Assuming that your built TypeScript module is scripts/client.js.)
The Start page for RequireJS or the Dojo Introduction to AMD modules are both resources that can tell you more about how to load AMD-formatted modules in a browser.
You got a really good technical answer from C Snover, but the answer you're actually looking for is "don't use external modules". By external modules, I mean "AMD" or "CommonJS" modules.
If you actually need what external modules offer, they can be very useful, but they come at a significant cost in terms of build/deployment complexity and concepts that you need to understand.
Just because external modules are way more complicated doesn't mean they're better; the TypeScript compiler itself is written using internal modules.
You can convert an external module back to an internal module by omitting any export statements on the module itself (and by not having an export = statement at the end of the file either). For example, this is an internal module:
module MyLibrary {
export class MyClass {
public Foo = 1;
}
}
If you are using internal modules, all you have to do is reference them in the right order via script tags in your HTML files and they will work without having to deal with any sort of loader system.
<script src="MyLibrary.js"></script>
<script src="MyUICode.js"></script>

Load Statically Linked GStreamer Plugin

I'm working on software for an embedded system that uses GStreamer 0.10.36. My goal is to keep the software as small as possible in terms of Flash memory space, so I'd like to statically linking the GStreamer plugins I need. According to the Core Reference Manual:
"There are options to statically link plugins to an app or even use
GStreamer without a plugin repository in which case gst_plugin_load()
can be needed to bring the plugin into memory. "
Unfortunately, it's not clear to me exactly what I need to do to bring the plugin into memory such that a subsequent call to gst_element_factory_make() completes successfully.
I'm doing the following:
Building GStreamer with --enable-static and --disable-registry set.
Linking the static library into my application
Call gst_element_factory_make() to create an element
Right now I'm only doing this for one plugin (tcpclientsink) out of several as an experiment. I had to edit the Makefile for that plugin to remove a --disable-static statement to get the libgsttcp.a file to build. I assume the library is good, but I'm not sure if there is a good way to verify that. gst-inspect does not appear to work on static libraries.
Note: If I call load_gst_plugin(/path/to/libgsttcp.a), GStreamer fails to load the plugin because of an invalid ELF header.
How does one load a statically linked GStreamer library?
I made an app in which all plugins are compiled inside the app (so it is self-containing)... Maybe this is another option for you, or do you really need to link to the library?
I got my usual code (plugin.c and plugin.h) that I used to compile the plugins in a shared library. I add an extra wrapper header that containts static registration code
static gboolean myplugin_init(GstPlugin * plugin)
{
gboolean ret;
gst_controller_init(NULL, NULL);
GST_DEBUG_CATEGORY_STATIC (gst_myplugin_debug);
GST_DEBUG_CATEGORY_INIT(gst_myplugin_debug, "myplugin", 0, "description");
ret = gst_element_register(plugin, "myplugin", GST_RANK_NONE, GST_TYPE_MECIMOTION);
return ret;
}
void gstmyplugins_register_static()
{
gst_plugin_register_static(
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"myplugin",
"description",
myplugin_init,
"0.0.1",
"LGPL",
"myplugins",
"GStreamer",
"http://gstreamer.net/");
gst_plugin_register_static(
...
}
then inside the code for my app i call this registration:
gstmyplugins_register_static();
then continue with
gst_element_factory_make("myplugin", NULL);
hope this helps.
With some help from the GStreamer developers I found the answer.... don't use version 0.10.36. :)
Basically the ability to build static plugin libraries was added/fixed in later versions. To get it to work in 0.10.36, I've had to back port changes from the GStreamer SDK and GStreamer 1.x into 0.10.36. Things are still a work in progress, but I am able to build libgstcoreelements.a and statically link with it. If I wasn't already building a modified version of 0.10.36, I probably would have just used the SDK.
Update
I created static versions of all of the libraries I'm using. My GStreamer library is now a bit of a hybrid between 0.10.36, the SDK, and 1.2.2, but it works. I wouldn't recommend this solution for anyone though. Use the SDK or version 1.x.

How do I create a standalone mode extension for ACE?

I'd like to extend ace with a mode for a custom language. As far as I can tell, the general process is:
Download the ace source.
Create a new lib/ace/mode/foo.js for your custom language.
run "make build" (or similar) to rebuild ACE.
Use the newly compiled build/src-min-no-conflict (or whatever) ACE distribution in your website.
But I want to just use an existing ACE distribution from their website, combined with my standalone new mode. I don't want to have to rebuild ACE as part of my build process in order to build my new mode. I got close by doing:
ace.config.setModuleUrl("foo-mode", "./foo.js");
session.setMode("foo-mode");
But I quickly ran into requirejs / dependency problems. For instance I couldn't do require("ace/mode/matching_brace_outdent") inside my mode. I temporarily hacked around that by first calling setMode('ace/mode/c_cpp') (which as a byproduct defines the matching_brace_outdent module). But I ran into even worse problems trying to get a custom WorkerClient to work.
Is my only option to build my mode as part of ACE? Or am I missing something?
Try the pre-built release.
https://github.com/ajaxorg/ace-builds/releases
You might need to edit other files (lists of modes etc.) depending on how you wish to present your new language in the UI:
With regards to require under no-conflict mode in custom modes that aren't workers, if you define your custom mode as a module or a series of modules inside define or ace.define, you should just be able to use the require provided to you in the function wrapper:
ace.define("ace/mode/your_module_name",
["require","exports","module","ace/your_other_dependencies"],
function(require, exports, module) {
// you can use require('...') here
});
I believe you can also use ace.require.
I am less sure about how to "manually build" a custom worker, but following this answer, I think I got it to work by copying code around the core of the relatively slim worker-json.js.

Resources