Is there any way to define a folder/file as a global module in browserify?
E.g:
var foo = require('../../../bar/');
OR
var foo = require('../../../bar/index.js');
to be
var foo = require('bar');
OR
var foo = require('bar/index.js');
You can do it by adding a browser field in your package.json file :
"browser": {
"bar": "../../../bar/index.js"
}
Then you have to import it by import 'bar'; in your main app file.
After that you can use it as a global module
var foo = require('bar');
Related
I want the contents / value of a CodeMirror 6 editor instance to be reflected in an external variable, when the text changes the variable changes / syncs.
How to do that in CodeMirror 6?
Pseudo Code
let sync_val = "";
import {EditorView} from "#codemirror/view"
import {EditorState} from "#codemirror/state"
let myView = new EditorView({
state: EditorState.create({doc: "hello"}),
parent: document.body
})
myView.onChange(function(val) {
sync_val = val;
});
The following works (use the updateListener extension):
let sync_val = "";
import {EditorView} from "#codemirror/view"
import {EditorState} from "#codemirror/state"
let myView = new EditorView({
state: EditorState.create({
doc: "hello",
extensions: [
EditorView.updateListener.of(function(e) {
sync_val = e.state.doc.toString();
})
]
}),
parent: document.body
})
I'd like to add the current module folder during my webpack compilation to my dist/ directory. For now, in /dist, I have something like that
const toCopy = [
'./../../../../node_modules/flatpickr/dist/flatpickr.min.js',
'./../../../../node_modules/flatpickr/dist/flatpickr.min.css',
]
this is the part of my webpack CopyPlugin
...
plugins: [
new CopyPlugin({
patterns: toCopy.map((entry) => {
console.log(entry);
return { from: entry }
})
})
]
And it gives me that
/dist
flatpickr.min.css
flatpickr.min.css
And I'd like that in order to avoid conflict if files from different modules have the same name .
for example, flatpickr as a ie.css, fr.js... but some other module could also have those files
/dist
/flatpickr
flatpickr.min.css
flatpickr.min.css
I've ended by created a loop over all my assets to copy to keep the CopyPlugin structure
const toCopy = new Map();
toCopy.set('popper', './../../contrib/bootstrap_sass/js/popper.min.js',);
toCopy.set('flatpickr', ['./../../../../node_modules/flatpickr/dist/flatpickr.min.js',
'./../../../../node_modules/flatpickr/dist/flatpickr.min.css']);
let toCopyFormatted = [];
for (let [dest, entries] of toCopy.entries()) {
if (typeof entries === 'string') {
let data = {to: dest}
data['from'] = entries;
toCopyFormatted.push(data);
} else {
entries.forEach(function (v, k) {
let data = {to: dest}
data['from'] = v;
toCopyFormatted.push(data);
})
}
}
Generally, is there a way to customize the app code during build step?
Specifically, there is the typical need to make requests from the application to the local backend ([1], [2], [3], [4]).
localhost doesn't work since the server and the app are on different hosts (when using Android emulator or an actual physical device).
The actual IP address of the host in the same network works but in a multi-developer project it's a hassle for everyone to constantly change the constant IP in the code to that of their development machine.
With Webpack a case like that could be solved with DefinePlugin replacing a placeholder with the IP address of the machine the build is happening on.
We ended up using somewhat hacky approach inspired by transformers like react-native-typescript-transformer or react-native-sass-transformer. It's idea is pretty much equivalent to the mentioned DefinePlugin of Webpack.
First, some transformer files in the project directory (you can name them however you like, just update the references):
configBuildReplacements.js
// whatever logic you need
module.exports = {
API_HOST_PLACEHOLDER: `http://${getLocalNetworkAddress()}:3000`,
SOME_OTHER_DYNAMIC_VALUE: someFun(),
}
configBuildReplaceTransformer.js
const semver = require('semver')
let upstreamTransformer = null
const reactNativeVersionString = require('react-native/package.json').version
const reactNativeMinorVersion = semver(reactNativeVersionString).minor
if (reactNativeMinorVersion >= 56) {
upstreamTransformer = require('metro/src/reactNativeTransformer')
}
else if (reactNativeMinorVersion >= 52) {
upstreamTransformer = require('metro/src/transformer')
}
else if (reactNativeMinorVersion >= 47) {
upstreamTransformer = require('metro-bundler/src/transformer')
}
else if (reactNativeMinorVersion === 46) {
upstreamTransformer = require('metro-bundler/build/transformer')
}
else {
// handle RN <= 0.45
const oldUpstreamTransformer = require('react-native/packager/transformer')
upstreamTransformer = {
transform({ src, filename, options }) {
return oldUpstreamTransformer.transform(src, filename, options)
},
}
}
module.exports.transform = function (src, filename, options) {
// handle RN >= 0.46
if (typeof src === 'object') {
({ src, filename, options } = src)
}
const replacements = require('./configBuildReplacements')
const modifiedSrc = Object.keys(replacements).reduce(
(src, replacementKey) => src.replace(
new RegExp(replacementKey, 'g'),
replacements[replacementKey],
),
src,
)
return upstreamTransformer.transform({
src: modifiedSrc,
filename,
options,
})
}
The exported transform function uses the exported object from the previous file configBuildReplacements.js as a dictionary to replace key substrings with value substrings in the source code before handing this code to the default (upstream) transformer.
And to connect this new transformer to the project:
with Expo, add the transformer packager option to app.json:
{
"expo": {
"packagerOpts": {
"transformer": "configBuildReplaceTransformer.js"
}
}
}
without Expo, add getTransformModulePath() to rn-cli.config.js (which is the default path to the optional config file for React Native CLI, which is extremely poorly documented at the moment of this writing):
module.exports = {
getTransformModulePath() {
return require.resolve('./configBuildReplaceTransformer')
},
}
After this is done, just like with DefinePlugin, code like
get('API_HOST_PLACEHOLDER/info')
will become something like
get('http://192.168.42.23:3000/info')
I'm working my way through the code of a Vue.js project.
In the file src/model/TextSegment.js the first two lines are:
import UniqueObject from "./UniqueObject";
import { TimeCode } from "#/model";
The file UniqueObject.js is a class file in the same directory, and so I understand that the ./ simply means the same directory and loads this file for use in TextSegment.js which extends this class.
But the file TimeCode.js is also a class in the same directory, albeit one that is instantiated, but I would expect it to be loaded with the same syntax, e.g.:
import TimeCode from "./TimeCode";
Why is TimeCode in squiggly brackets?
Why does it have a # instead of a . as a directory?
src/model/UniqueObject.js
import uuidv4 from "uuid/v4";
class UniqueObject {
constructor(initial = {}) {
if (this.constructor == UniqueObject) {
throw TypeError("Cannot instantiate abstract class UniqueObject");
}
this.uuid = initial.uuid || uuidv4();
}
}
export default UniqueObject;
src/model/TimeCode.js
class TimeCode {
constructor(initials = {}) {
this.seconds = initials.seconds || null;
this.frame = initials.frame || null;
}
}
export default TimeCode;
src/model/TextSegment.js
import UniqueObject from "./UniqueObject";
import { TimeCode } from "#/model";
class TextSegment extends UniqueObject {
constructor(initials = {}) {
super(initials);
this.content = initials.content || "";
this.translation = initials.translation || "";
this.notes = initials.notes || "";
this.timecode_start = new TimeCode(initials.timecode_start || {});
this.timecode_end = new TimeCode(initials.timecode_end || {});
this.voice_id = initials.voice_id || null;
this.filename = initials.filename || "";
}
}
export default TextSegment;
There are several ways of importing in JavaScript. These are the two most common ones.
import UniqueObject from "./UniqueObject"; imports the default export variable. If you open the UniqueObject file you would most likely see something like export default <var>.
import { TimeCode } from "#/model"; imports the TimeCode variable in the file at #/model. If you open the model file you would see something like export const TimeCode.
The # has to do with your module loader and depends on which module loader you use.
How do we organize our test directory when developing some libraries that uses Native js code?
I tried to work this out, but I'm blocked here, with this error at runtime when running test/test.sh:
Elm.Native.Mylib = {};
^
TypeError: Cannot read property 'Native' of undefined
git repository
My directories are structured this way:
Mylib:
- src :
- Mylib.elm
- Native :
- MyLib.js
- tests :
- Test.elm
- Test.sh
- elm-package.json
the tests/elm-package.json contains :
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
,"../src"
],
"exposed-modules": [],
"native-modules": true,
"dependencies": {
"elm-community/elm-test": "1.1.0 <= v < 2.0.0",
"elm-lang/core": "4.0.1 <= v < 5.0.0"
},
"elm-version": "0.17.0 <= v < 0.18.0"
}
the tests/Test.elm is :
module Main exposing (..)
import Basics exposing (..)
import ElmTest exposing (..)
import Mylib exposing (..)
tests : Test
tests =
suite "elm-Mylib Library Tests"
[ ]
main =
runSuite tests
The tests/test.sh is
#!/bin/sh
elm-package install -y
elm-make --yes --output test.js Test.elm
node test.js
The src/Mylib.elm is
module Mylib exposing (..)
import Native.Mylib exposing (..)
import Task exposing (Task)
import Time exposing (Time)
print : a -> Task x ()
print value =
Native.Mylib.log (toString value)
getCurrentTime : Task x Time
getCurrentTime =
Native.Mylib.getCurrentTime
The src/Native/Mylib.js is
Elm.Native.Mylib = {};
Elm.Native.Mylib.make = function(localRuntime) {
localRuntime.Native = localRuntime.Native || {};
localRuntime.Native.Mylib = localRuntime.Native.Mylib || {};
if (localRuntime.Native.Mylib.values)
{
return localRuntime.Native.Mylib.values;
}
var Task = Elm.Native.Task.make(localRuntime);
var Utils = Elm.Native.Utils.make(localRuntime);
function log(string)
{
return Task.asyncFunction(function(callback) {
console.log(string);
return callback(Task.succeed(Utils.Tuple0));
});
}
var getCurrentTime = Task.asyncFunction(function(callback) {
return callback(Task.succeed(Date.now()));
});
return localRuntime.Native.Mylib.values = {
log: log,
getCurrentTime: getCurrentTime
};
};
Try this:
var _user$project$Native_MyLib = function() {
return {
exported: function(arg) { return "One" },
exported2: F2(function(arg) { return "Two" }),
exported3: F3(function(arg) { return "Three" }),
}
}();
It works for grater than Elm 0.17.
Buy you should also use full qualified import:
import Natve.MyLib
exported : String -> String
Native.MyLib.exported
exported2 : String -> String -> String
Native.MyLib.exported2
exported3 : String -> String -> String -> String
Native.MyLib.exported3
User and project values are from your/local elm-package.json:
"repository": "https://github.com/user/project.git",