1672495020
ImportJS is a tool to automatically import dependencies in your JavaScript project. Use it along with one of our editor integrations for Atom, Emacs, Sublime, Vim, or VS Code.
There are ImportJS plugins for the following editors:
Detailed instructions on how to install ImportJS can be found in the editor links above.
Want to add another editor to the list? See how to contribute.
ImportJS uses Babel 7 from version 3.1.0. In most cases, Babel 7 is backwards-compatible with Babel 6, but if you run into issues (such as this one about decorators), consider installing a previous version of ImportJS (e.g. 3.0.0) or updating your project to be Babel 7 compatible.
Let's say that you have a JavaScript project with the following structure:
.
|-- index.html
|-- components
| |-- button.js
| |-- icon.js
|-- vendor
| |--
|-- pages
| |-- index.js
Now, imagine that you're editing pages/index.js
which contains:
document.createElement(new Button({ text: 'Save' }).toDOMElement());
At this point, Button
is undefined, so we need to import it. If you are used to doing this manually, this involves figuring out the path to the JavaScript module that defines Button
. With ImportJS you instead place your cursor on the word "Button", then hit <leader>j
(Vim), (M-x) import-js-import
(Emacs), or choose "ImportJS: import word under cursor" (Sublime). The file buffer will now change to the following:
import Button from '../components/button';
document.createElement(new Button({ text: 'Save' }).toDOMElement());
That's basically it. ImportJS will help you find modules and automatically add import
statements. But, keep reading for more neat features.
ImportJS can be used to automatically fix all imports in the current file. By hitting <leader>i
(Vim), (M-x) import-js-fix
(Emacs), or choose ImportJS: fix all imports
(Sublime), all your undefined variables will be resolved, and all your unused imports will be removed.
If you're using JSX, ImportJS will automatically import React
for you.
Since ImportJS is pretty good at finding JS modules, it makes sense that there's an option to open/go to a file rather than import it. This is similar to Vim's built in "Open file under cursor". Use it by placing the cursor on a variable and hit <leader>g
(Vim), (M-x) import-js-goto
(Emacs), or choose "ImportJS: goto module" (Sublime).
.js\*
and .ts*
are considered when importinggroupImports
and sortImports
configuration options. Comments and whitespace will be preserved if these are both disabled.ImportJS is configured through a JavaScript file (.importjs.js
).
The file needs to export a single object containing you configuration settings, like the example below.
module.exports = {
excludes: [
'./react-components/**/test/**'
]
// continue with the rest of your settings...
}
Save this file in the root folder of your project (e.g. where the package.json file is found). You can also save it to the user home directory if you want to share a global config between different projects.
The following configuration options are supported.
aliases
declarationKeyword
environments
excludes
globals
groupImports
ignorePackagePrefixes
importDevDependencies
importFunction
importStatementFormatter
logLevel
maxLineLength
minimumVersion
moduleNameFormatter
namedExports
sortImports
stripFileExtensions
danglingCommas
tab
useRelativePaths
mergableOptions
excludes
Define a list of glob patterns that match files and directories that you don't want to include for importing.
excludes: [
'./react-components/**/test/**',
]
aliases
Some variable names might not easily map to a file in the filesystem. For those, you can add them to the aliases
configuration.
aliases: {
$: 'third-party-libs/jquery',
_: 'third-party-libs/underscore',
}
Aliases can be made dynamic by using the {filename}
string. This part of the alias will be replaced by the name of the file you are currently editing.
e.g.
aliases: {
styles: './{filename}.scss',
}
will for a file foo/bar.js
result in
import styles from './bar.scss';
environments
This list of environments controls what core modules are available when importing, and what variables are considered global by default. The supported values right now are
['meteor']
- make the core modules for Meteor available, and add a bunch of meteor globals['node']
- make all the core modules for Node available, and add a bunch of node globals['browser']
- add a bunch of browser globals['jasmine']
- add a bunch of jasmine globals['jest']
- add a bunch of jest globalsenvironments: ['meteor', 'node']
namedExports
*Note: Since 2.1.0 ImportJS finds your named exports automatically. Most likely you don't need this option. If you end up having to use this configuration anyway, there might be a bug in the exports-finding parts of ImportJS. File an issue and tell us about it!
If you have an ES6/ES2015 module that exports multiple things (named exports), or a CommonJS module that exports an object with properties on it that you want to destructure when importing, you can add those to a namedExports
configuration option.
namedExports: {
underscore: [
'omit',
'debounce',
'memoize'
],
'lib/utils': [
'escape',
'hasKey',
],
}
Imports that use the import
declaration keyword then use named imports syntax. e.g.
import { memoize } from 'underscore';
memoize(() => { foo() });
and imports that use const
or var
use [ES2015 Destructuring Assigment][destructing assignment], e.g.
const { memoize } = require('underscore');
memoize(() => { foo() });
The key used to describe the named exports should be a valid import path. This can be e.g. the name of a package found under node_modules
, a path to a module you created yourself, or a relative import path.
Consider the example as a valid use case for the namedExports
property. Let's say we have a file:
import { Provider } from 'react-redux';
import React from 'react';
import store from './redux/redux-store';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>,
document.getElementById('root')
);
And we're going to import BrowserRouter
but instead of the desired result we get the No JS module to import for BrowserRouter
message. In order to fix the problem, populate namedExports
in your config file as follows:
namedExports: {
'react-router-dom': ['BrowserRouter', 'Route', 'Redirect']
}
After that we are able to import BrowserRouter
correctly. The resulting import statement will look like this:
import { BrowserRouter } from 'react-router-dom'
declarationKeyword
The default value for this property is import
, making your import statements use the ES2015 modules syntax:
import Foo from 'foo';
If you aren't ready for ES2015 yet, you have the option to use var
or const
instead.
declarationKeyword: 'const'
In such case, your import statements will look something like this:
var Foo = require('foo'); // "declarationKeyword": "var"
const Foo = require('foo'); // "declarationKeyword": "const"
globals
Provide a list of global identifiers used in the code. ImportJS will ignore these when trying to import all undefined variables.
Note: If you use the environments
configuration option correctly, you might not need to specify globals.
groupImports
By default, ImportJS will put imports into groups:
You can turn off this behavior by setting groupImports
to false
. When disabled, imports are listed alphabetically in one list.
groupImports: false
sortImports
By default, ImportJS will sort imports by the name or path of the imported module.
You can turn off this behavior by setting sortImports
to false
. When disabled, existing imports are not rearranged, and new imports are always added above existing imports.
sortImports: false
emptyLineBetweenGroups
By default, ImportJS will insert empty line between import groups.
You can turn off this behavior by setting emptyLineBetweenGroups
to false
.
emptyLineBetweenGroups: false
importDevDependencies
ImportJS will look for package dependencies listed in package.json
when importing. By default, only modules listed under dependencies
and peerDependencies
will be used. By setting importDevDependencies
to true
, devDependencies
will also be taken into account.
importDevDependencies: true
danglingCommas
By default, ImportJS will add trailing commas when constructing import statements with multiple named imports.
You can turn off this behavior by setting danglingCommas
to false
.
danglingCommas: false
importFunction
Note: this only applies if you are using var
or const
as declarationKeyword
.
The default value for this configuration option is "require"
, which is the standard CommonJS function name used for importing.
importFunction: 'myCustomRequireFunction'
stripFileExtensions
An array that controls what file extensions are stripped out from the resulting import statement. The default configuration strips out [".js", ".jsx", ".ts", ".tsx"]
. Set to an empty array []
to avoid stripping out extensions.
stripFileExtensions: ['.web.js', '.js']
useRelativePaths
This option is enabled by default. When enabled, imports will be resolved relative to the current file being edited.
import Foo from './foo';
import Bar from '../baz/bar';
You can disable this by setting it to false:
useRelativePaths: false
Package dependencies (located in node_modules
) will not be imported relatively.
ignorePackagePrefixes
If you have package dependencies specified in package.json
that are prefixed with e.g. an organization name but want to be able to import these without the package prefix, you can set the ignorePackagePrefixes
configuration option.
ignorePackagePrefixes: ['my-company-']
When package dependencies are matched, these prefixes will be ignored. As an example, a variable named validator
would match a package named my-company-validator
.
minimumVersion
Setting minimumVersion
will warn people who are running a version of ImportJS that is older than what your .importjs.js
configuration file requires. If your plugin version is older than this value, you will be shown a warning that encourages you to upgrade your plugin.
minimumVersion: '1.0.0'
maxLineLength
Defaults to 80
. This setting controls when import statements are broken into multiple lines.
maxLineLength: 70
moduleNameFormatter
Use a function here to control how the resulting module name string will look like. It's useful if you for instance want to add a custom prefix to certain imports. Apart from the standard pathToCurrentFile
and pathToImportedModule
values passed in to all configuration functions, this method is also passed a moduleName
value, which in general is what you want to manipulate.
moduleNameFormatter({ moduleName, pathToCurrentFile }) {
if (/-test/.test(pathToCurrentFile)) {
// Import a mocked version in test files
return `mocks/${moduleName}`;
}
if (moduleName.startsWith('foo')) {
// Add a leading slash to foo imports
return `/${moduleName}`;
}
// Fall back to the original specifier. It's important that this function
// always returns a string.
return moduleName;
},
importStatementFormatter
Use a function here to control how the resulting import statement will look like. This is useful if you for instance want to strip out trailing semicolons (that ImportJS adds by default).
Note: this method should only be used in rare cases. There's a chance that ImportJS won't be able to recognize the resulting import statement next time it is about to import something.
importStatementFormatter({ importStatement }) {
return importStatement.replace(/;$/, '');
},
tab
Defaults to two spaces (" "
). This setting controls how indentation is constructed when import statements are broken into multiple lines.
tab: '\t'
logLevel
One of ["debug", "info", "warn", "error"]
. This controls what ends up in the logfile. The default is info
.
logLevel: 'debug'
The logfile is written to "importjs.log" in your operating system's default directory for temporary files. You can get the path to the log file by running importjs logpath
.
mergableOptions
A dictionary of Options that be merged with defaults and values provided by an environment
. This can be used to overwrite options provided by environments. Defaults to:
mergableOptions: {
aliases: true,
coreModules: true,
namedExports: true,
globals: true,
}
Note: the mergableOptions
option will always be merged and will be ignored if included in a user config.
To disable merging a particular option or set of options, set the key to false
:
mergableOptions: {
globals: false
}
For example, if you are using the meteor
environment but want to explicitly import modules which are provided as globals, you can use this setting to overwrite the environment globals.
const globals = require('globals');
module.exports = {
environments: ['meteor', 'node'],
mergableOptions: {
globals: false // Overwrite globals
},
globals: [
// Add the globals you want back in
...Object.keys(globals.builtin), // include javascript builtins
...Object.keys(globals.node), // include node globals
'Package', 'Npm' // Include meteor globals for `package.js` files
]
}
Different sections of your application may have special importing needs. For instance, your tests might need the 'const'
declaration keyword, but the rest of your application can use 'import'
. To be able to target these special cases, you can turn your configuration option into a function. When ImportJS resolves a configuration option, it will check to see if a function is used. In such case, the function is invoked with the following arguments:
pathToCurrentFile
: (always available) A path to the file you are editing.pathToImportedModule
(not available for some options) A path to the file/module you are importing.Here's an example of how to dynamically control the declarationKeyword
configuration option based on the file you are importing:
// .importjs.js
function isTestFile(path) {
return path.endsWith('-test.js');
}
module.exports = {
declarationKeyword({ pathToImportedModule }) {
if (isTestFile(pathToImportedModule)) {
return 'const';
}
return 'import';
},
}
Here's a more elaborate example taking both pathToImportedModule
and pathToCurrentFile
into account:
module.exports = {
useRelativePaths({ pathToImportedModule, pathToCurrentFile }) {
if (pathToCurrentFile.endsWith('-mock.js')) {
return false;
}
if (pathToImportedModule.endsWith('-test.js')) {
return false;
}
return true;
},
}
In order to use functions, you need to use the JavaScript configuration file (.importjs.js
).
ImportJS comes with a handy command-line tool that can help you perform importing outside of an editor. Under the hood, this is what most of the editor integrations use.
⨠ importjs --help
Usage: importjs [options] [command]
Commands:
word [options] <word> <pathToFile>
search [options] <word> <pathToFile>
fix [options] <pathToFile>
rewrite [options] <pathToFile>
add [options] <imports> <pathToFile>
goto <word> <pathToFile>
start [options] start a daemon
cachepath show path to cache file
logpath show path to log file
Options:
-h, --help output usage information
-V, --version output the version number
Examples:
$ importjs word someModule path/to/file.js
$ importjs search someModule* path/to/file.js
$ importjs fix path/to/file.js
$ importjs rewrite --overwrite path/to/file.js
$ importjs add '{ "foo": "path/to/foo", "bar": "path/to/bar" }' path/to/file.js
$ importjs goto someModule path/to/file.js
$ importjs cachepath
$ importjs logpath
$ importjs start --parent-pid=12345
If you want to change how imports are constructed in an existing project, you can use the command-line tool in combination with find
to batch-update a set of files. E.g.
find ./app -name "**.js*" -exec importjs rewrite --overwrite {} \;
Since the --overwrite
flag makes ImportJS destructive (files are overwritten), it's a good thing to double-check that the find
command returns the right files before adding the -exec
part.
ImportJS looks for the package.json
file in the closest ancestor directory for the file you're editing to find node modules to import. However, sometimes it might pull dependencies from a directory further up the chain. For example, your directory structure might look like this:
.
|-- package.json
|-- components
| |-- button.js
| |-- icon.js
|-- node_modules
| |-- react
|-- subpackage
| |-- package.json
| |-- components
| |-- bulletin.js
If you were to use ImportJS on subpackage/components/bulletin.js
which imports React, ImportJS would not know that react
is a valid dependency.
To tell ImportJS to skip a directory and keep searching upwards to find the root package directory, specify "importjs": { "isRoot": false }
in the package.json
of the directory to ignore. In this case, you would want something like this:
{
"name": "subpackage",
...
"importjs": {
"isRoot": false
}
}
Note: This section is intended mostly for developers of editor plugins. If you are using one of the standard editor plugins, you are most likely using the daemon under the hood already.
You can run ImportJS in a background process and communicate with it using stdin
and stdout
. This will make importing faster because we're not spinning up a node environment on every invocation.
The daemon is started by running running importjs
. It accepts commands sent via stdin
. Each command is a (oneline) JSON string ending with a newline. The command structure is basically the same as for the command-line tool, but wrapped in JSON instead of expressed on the command line. Here are a few examples:
Run fix imports
:
{
"command": "fix",
"fileContent": "const foo = bar();\n",
"pathToFile": "foo.js",
}
Import a single word:
{
"command": "word",
"commandArg": "bar",
"fileContent": "const foo = bar();\n",
"pathToFile": "foo.js",
}
Goto:
{
"command": "goto",
"commandArg": "bar",
"fileContent": "const foo = bar();\n",
"pathToFile": "foo.js",
}
Results are printed to stdout
in JSON format. The response will look the same as what the command-line tool produces. If an error occurs, it will also end up in stdout
as JSON (an object with an error
key).
On startup, the daemon will print a path to a logfile. If you want to find out what's going on behind the scenes, you can inspect this file. If you don't have access to the console log of the daemon, you'll find the logfile in os.tmpdir() + '/importjs.log
(which will resolve to something like var/folders/1l/_t6tm7195nd53936tsvh2pcr0000gn/T/importjs.log
on a Mac).
If you have a large application, traversing the file system to find modules can be slow. That's why ImportJS has built-in integration with Watchman, a fast and robust file watching service developed by Facebook. All you have to do to get a performance boost is to install watchman locally, and make sure to use an up-to-date editor plugin (Watchman is only used when ImportJS is run as a daemon).
See the CONTRIBUTING.md document for tips on how to run, test and develop ImportJS locally.
Happy hacking!
Author: Galooshi
Source Code: https://github.com/Galooshi/import-js
License: MIT license
#atom #vim #sublime #javascript
1656982800
Hoje, continuo compartilhando minha experiência com o Módulo Nativo e C++.
Como veremos muitas bibliotecas C/C++ escrevendo para plataformas móveis, precisamos implementá-las em nosso aplicativo iOS ou React Native. É por isso que quero escrever um artigo sobre como exportar uma função de C++ para React Native, que é fácil de entender e economiza tempo para iniciantes. Vou começar com um novo aplicativo nativo de reação
npx react-native init NativeModules
Crie um novo arquivo C++ e nomeie-oCpp_to_RN.cpp
Quando criamos um novo arquivo C++, o Xcode criará um arquivo de cabeçalho Cpp_to_RN.hpp
para nós
Primeiro, abra o arquivo “ Cpp_to_RN.hpp
” e crie uma classe que inclua uma função sem o corpo.
#ifndef Cpp_to_RN_hpp
#define Cpp_to_RN_hpp#include <stdio.h>
#include <string>class Cpp_to_RN {
public:
std::string sayHello();
};#endif /* Cpp_to_RN_hpp */
Em seguida, abra o Cpp_to_RN.cpp
arquivo e escreva uma função simples “ sayHello()
”
#include "Cpp_to_RN.hpp"
std::string Cpp_to_RN::sayHello(){
return "Hello from CPP";
}
Para encapsular os arquivos C++ e exportá-los para o lado IOS (swift)
uma. Crie um arquivo Objective C e nomeie-oCpp_to_RN.m
Renomeie o Cpp_to_RN.m
para Cpp_to_RN.mm
b. Abra o WrapCpp_to_RN.mm
arquivo e escreva o conteúdo do corpo que envolverá a função sayHello
do arquivo C++.
#import <Foundation/Foundation.h>
#import "WrapCpp_to_RN.h"
#import "Cpp_to_RN.hpp"@implementation WrapCpp_to_RN- (NSString *) sayHello {
Cpp_to_RN fromCPP;
std::string helloWorldMessage = fromCPP.sayHello();
return [NSString
stringWithCString:helloWorldMessage.c_str()
encoding:NSUTF8StringEncoding];
}
@end
c. Crie um arquivo de cabeçalho e nomeie-oWrapCpp_to_RN.h
Exporte a wrapSayHello
função para o arquivo Swift
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Para exportar a função C++ para React Native
uma. Crie um arquivo Swift e nomeie-oSendCpp_to_RN.swift
Observação: o Xcode nos pedirá para criar um NativeModules-Bridging-Header.h
arquivo para nós.
Crie uma classe SendCpp_to_RN
e declare-a comoNSObject
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Escreva uma função requiresMainQueueSetup()
para evitar avisos quando executamos o aplicativo
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Escreva uma função para envolver o WrapCpp_to_RN()
fromWrapCpp_to_RN.mm
import Foundation@objc(SendCpp_to_RN)
class SendCpp_to_RN : NSObject {
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
@objc func fromCpp(_ successCallback: RCTResponseSenderBlock) -> Void {
successCallback([NSNull(), WrapCpp_to_RN().wrapSayHello() as Any])
}}
b. Exporte uma função wrap no arquivo Swift para React Native
Crie um arquivo Objective C para exportar a classe Swift e sua função usandoCallback
#import <React/RCTBridgeModule.h>
#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"
@interface RCT_EXTERN_MODULE(SendCpp_to_RN, NSObject)RCT_EXTERN_METHOD(fromCpp:(RCTResponseSenderBlock)successCallback)@end
c. Conecte o Swift ao React Native, abra o NativeModules-Bridging-Header.h
arquivo
#import <React/RCTBridgeModule.h>#import <React/RCTViewManager.h>#import "WrapCpp_to_RN.h"
Chame a classe Swift e suas funções
import React from 'react';
import {StyleSheet, Text, View, NativeModules, Button} from 'react-native';const App = () => {
const onPress = () => {
const {SendCpp_to_RN} = NativeModules;
SendCpp_to_RN.fromCpp((_err, res) => console.log(res));
};
return (
<View style={styles.container}>
<Text> Practice !</Text>
<Button title="C++ to React Native" color="#841584" onPress={onPress} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
E pronto, basta executar o aplicativo
react-native run-ios
Ou apenas clique no botão “executar” no Xcode e veja o que fizemos.
Espero que meu artigo seja útil para você, obrigado pelo tempo de leitura.
1656981060
今日も、ネイティブモジュールとC++での経験を共有し続けています。
多くのC/C ++ライブラリがモバイルプラットフォーム用に作成されているので、それらをiOSまたはReactNativeアプリケーションに実装する必要があります。そのため、関数をC++からReactNativeにエクスポートする方法についての記事を書きたいと思います。これは、理解しやすく、初心者の時間を節約できます。新しいreactネイティブアプリケーションから始めます
npx react-native init NativeModules
新しいC++ファイルを作成し、名前を付けますCpp_to_RN.cpp
新しいC++ファイルを作成すると、XcodeはヘッダーファイルCpp_to_RN.hpp
を作成します
まず、「Cpp_to_RN.hpp
」ファイルを開き、本体のない関数を含むクラスを作成します。
#ifndef Cpp_to_RN_hpp
#define Cpp_to_RN_hpp#include <stdio.h>
#include <string>class Cpp_to_RN {
public:
std::string sayHello();
};#endif /* Cpp_to_RN_hpp */
次に、ファイルを開いてCpp_to_RN.cpp
、単純な関数「sayHello()
」を記述します。
#include "Cpp_to_RN.hpp"
std::string Cpp_to_RN::sayHello(){
return "Hello from CPP";
}
C ++ファイルをラップしてIOS(swift)側にエクスポートするには
a。ObjectiveCファイルを作成して名前を付けますCpp_to_RN.m
名前をに変更Cpp_to_RN.m
します Cpp_to_RN.mm
b。ファイルを開き、C++ファイルからWrapCpp_to_RN.mm
関数をラップする本文のコンテンツを記述します。sayHello
#import <Foundation/Foundation.h>
#import "WrapCpp_to_RN.h"
#import "Cpp_to_RN.hpp"@implementation WrapCpp_to_RN- (NSString *) sayHello {
Cpp_to_RN fromCPP;
std::string helloWorldMessage = fromCPP.sayHello();
return [NSString
stringWithCString:helloWorldMessage.c_str()
encoding:NSUTF8StringEncoding];
}
@end
c。ヘッダーファイルを作成し、名前を付けますWrapCpp_to_RN.h
wrapSayHello
関数をSwiftファイルにエクスポートします
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
C++関数をReactNativeにエクスポートするには
a。Swiftファイルを作成し、名前を付けますSendCpp_to_RN.swift
注:Xcodeは、NativeModules-Bridging-Header.h
ファイルを作成するように要求します。
クラスSendCpp_to_RN
を作成し、次のように宣言しますNSObject
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
requiresMainQueueSetup()
アプリケーション実行時の警告を防ぐ関数を作成する
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
WrapCpp_to_RN()
fromをラップする関数を記述しますWrapCpp_to_RN.mm
import Foundation@objc(SendCpp_to_RN)
class SendCpp_to_RN : NSObject {
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
@objc func fromCpp(_ successCallback: RCTResponseSenderBlock) -> Void {
successCallback([NSNull(), WrapCpp_to_RN().wrapSayHello() as Any])
}}
b。Swiftファイルのラップ関数をReactNativeにエクスポートします
を使用してSwiftクラスとその関数をエクスポートするObjectiveCファイルを作成しますCallback
#import <React/RCTBridgeModule.h>
#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"
@interface RCT_EXTERN_MODULE(SendCpp_to_RN, NSObject)RCT_EXTERN_METHOD(fromCpp:(RCTResponseSenderBlock)successCallback)@end
c。SwiftをReactNativeに接続し、NativeModules-Bridging-Header.h
ファイルを開きます
#import <React/RCTBridgeModule.h>#import <React/RCTViewManager.h>#import "WrapCpp_to_RN.h"
Swiftクラスとその関数を呼び出す
import React from 'react';
import {StyleSheet, Text, View, NativeModules, Button} from 'react-native';const App = () => {
const onPress = () => {
const {SendCpp_to_RN} = NativeModules;
SendCpp_to_RN.fromCpp((_err, res) => console.log(res));
};
return (
<View style={styles.container}>
<Text> Practice !</Text>
<Button title="C++ to React Native" color="#841584" onPress={onPress} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
これで完了です。アプリケーションを実行するだけです。
react-native run-ios
または、Xcodeの「実行」ボタンをクリックして、実行内容を確認してください。
私の記事がお役に立てば幸いです。お読みいただきありがとうございます。
1656979200
Aujourd'hui, je continue à partager mon expérience avec le module natif et C++.
Comme nous verrons beaucoup de bibliothèques C/C++ écrire pour les plates-formes mobiles, nous devons les implémenter dans notre application iOS ou React Native. C'est pourquoi je souhaite écrire un article sur la façon d'exporter une fonction de C++ vers React Native, ce qui est facile à comprendre et fait gagner du temps aux débutants. Je vais commencer avec une nouvelle application native réactive
npx react-native init NativeModules
Créez un nouveau fichier C++ et nommez-leCpp_to_RN.cpp
Lorsque nous créons un nouveau fichier C++, Xcode créera un fichier d'en-tête Cpp_to_RN.hpp
pour nous
Tout d'abord, ouvrez le fichier " Cpp_to_RN.hpp
" et créez une classe qui inclut une fonction sans le corps.
#ifndef Cpp_to_RN_hpp
#define Cpp_to_RN_hpp#include <stdio.h>
#include <string>class Cpp_to_RN {
public:
std::string sayHello();
};#endif /* Cpp_to_RN_hpp */
Ouvrez ensuite le Cpp_to_RN.cpp
fichier et écrivez une fonction simple " sayHello()
"
#include "Cpp_to_RN.hpp"
std::string Cpp_to_RN::sayHello(){
return "Hello from CPP";
}
Pour envelopper les fichiers C++ et les exporter vers le côté IOS (swift)
un. Créez un fichier Objective C et nommez-leCpp_to_RN.m
Renommez le Cpp_to_RN.m
en Cpp_to_RN.mm
b. Ouvrez le WrapCpp_to_RN.mm
fichier et écrivez le contenu du corps qui encapsulera la fonction sayHello
à partir du fichier C++.
#import <Foundation/Foundation.h>
#import "WrapCpp_to_RN.h"
#import "Cpp_to_RN.hpp"@implementation WrapCpp_to_RN- (NSString *) sayHello {
Cpp_to_RN fromCPP;
std::string helloWorldMessage = fromCPP.sayHello();
return [NSString
stringWithCString:helloWorldMessage.c_str()
encoding:NSUTF8StringEncoding];
}
@end
c. Créez un fichier d'en-tête et nommez-leWrapCpp_to_RN.h
Exporter la wrapSayHello
fonction vers le fichier Swift
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Pour exporter la fonction C++ vers React Native
un. Créez un fichier Swift et nommez-leSendCpp_to_RN.swift
Remarque : Xcode nous demandera de créer un NativeModules-Bridging-Header.h
fichier pour nous.
Créez une classe SendCpp_to_RN
et déclarez-la commeNSObject
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Écrire une fonction requiresMainQueueSetup()
pour empêcher l'avertissement lorsque nous exécutons l'application
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Ecrire une fonction pour envelopper le WrapCpp_to_RN()
fromWrapCpp_to_RN.mm
import Foundation@objc(SendCpp_to_RN)
class SendCpp_to_RN : NSObject {
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
@objc func fromCpp(_ successCallback: RCTResponseSenderBlock) -> Void {
successCallback([NSNull(), WrapCpp_to_RN().wrapSayHello() as Any])
}}
b. Exporter une fonction wrap dans un fichier Swift vers React Native
Créez un fichier Objective C pour exporter la classe Swift et sa fonction à l'aide deCallback
#import <React/RCTBridgeModule.h>
#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"
@interface RCT_EXTERN_MODULE(SendCpp_to_RN, NSObject)RCT_EXTERN_METHOD(fromCpp:(RCTResponseSenderBlock)successCallback)@end
c. Connectez Swift à React Native, ouvrez le NativeModules-Bridging-Header.h
fichier
#import <React/RCTBridgeModule.h>#import <React/RCTViewManager.h>#import "WrapCpp_to_RN.h"
Appelez la classe Swift et ses fonctions
import React from 'react';
import {StyleSheet, Text, View, NativeModules, Button} from 'react-native';const App = () => {
const onPress = () => {
const {SendCpp_to_RN} = NativeModules;
SendCpp_to_RN.fromCpp((_err, res) => console.log(res));
};
return (
<View style={styles.container}>
<Text> Practice !</Text>
<Button title="C++ to React Native" color="#841584" onPress={onPress} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
Et nous avons terminé, il suffit de lancer l'application
react-native run-ios
Ou cliquez simplement sur le bouton "exécuter" sur Xcode et voyez ce que nous avons fait.
J'espère que mon article vous sera utile, merci pour le temps de lecture.
1656981000
Hôm nay, tôi tiếp tục chia sẻ kinh nghiệm của mình với Native Module và C ++.
Vì chúng ta sẽ thấy rất nhiều thư viện C / C ++ viết cho nền tảng di động, chúng ta cần triển khai chúng cho ứng dụng iOS hoặc React Native của mình. Đó là lý do mình muốn viết một bài hướng dẫn cách export một hàm từ C ++ sang React Native dễ hiểu và tiết kiệm thời gian cho người mới bắt đầu. Tôi sẽ bắt đầu với một ứng dụng gốc phản ứng mới
npx react-native init NativeModules
Tạo một tệp C ++ mới và đặt tên cho nóCpp_to_RN.cpp
Khi chúng tôi tạo tệp C ++ mới, Xcode sẽ tạo tệp tiêu đề Cpp_to_RN.hpp
cho chúng tôi
Đầu tiên, mở tệp Cpp_to_RN.hpp
“” và tạo một lớp bao gồm một hàm không có phần thân.
#ifndef Cpp_to_RN_hpp
#define Cpp_to_RN_hpp#include <stdio.h>
#include <string>class Cpp_to_RN {
public:
std::string sayHello();
};#endif /* Cpp_to_RN_hpp */
Sau đó, mở Cpp_to_RN.cpp
tệp và viết một hàm đơn giản “ sayHello()
”
#include "Cpp_to_RN.hpp"
std::string Cpp_to_RN::sayHello(){
return "Hello from CPP";
}
Để bọc các tệp C ++ và xuất chúng sang phía IOS (nhanh chóng)
một. Tạo một tệp Objective C và đặt tên cho nóCpp_to_RN.m
Đổi tên Cpp_to_RN.m
thành Cpp_to_RN.mm
b. Mở WrapCpp_to_RN.mm
tệp và viết nội dung phần nội dung sẽ bọc hàm sayHello
từ tệp C ++.
#import <Foundation/Foundation.h>
#import "WrapCpp_to_RN.h"
#import "Cpp_to_RN.hpp"@implementation WrapCpp_to_RN- (NSString *) sayHello {
Cpp_to_RN fromCPP;
std::string helloWorldMessage = fromCPP.sayHello();
return [NSString
stringWithCString:helloWorldMessage.c_str()
encoding:NSUTF8StringEncoding];
}
@end
c. Tạo một tệp tiêu đề và đặt tên cho nóWrapCpp_to_RN.h
Xuất wrapSayHello
hàm sang tệp Swift
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Để xuất hàm C ++ sang React Native
một. Tạo một tệp Swift và đặt tên cho nóSendCpp_to_RN.swift
Lưu ý: Xcode sẽ yêu cầu chúng tôi tạo một NativeModules-Bridging-Header.h
tệp cho chúng tôi.
Tạo một lớp SendCpp_to_RN
và khai báo nó làNSObject
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Viết một hàm requiresMainQueueSetup()
để ngăn cảnh báo khi chúng tôi chạy ứng dụng
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
Viết một hàm để bọc WrapCpp_to_RN()
từWrapCpp_to_RN.mm
import Foundation@objc(SendCpp_to_RN)
class SendCpp_to_RN : NSObject {
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
@objc func fromCpp(_ successCallback: RCTResponseSenderBlock) -> Void {
successCallback([NSNull(), WrapCpp_to_RN().wrapSayHello() as Any])
}}
b. Xuất một hàm bọc trong tệp Swift sang React Native
Tạo một tệp Objective C để xuất lớp Swift và chức năng của nó bằng cách sử dụngCallback
#import <React/RCTBridgeModule.h>
#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"
@interface RCT_EXTERN_MODULE(SendCpp_to_RN, NSObject)RCT_EXTERN_METHOD(fromCpp:(RCTResponseSenderBlock)successCallback)@end
c. Kết nối Swift với React Native, mở NativeModules-Bridging-Header.h
tệp
#import <React/RCTBridgeModule.h>#import <React/RCTViewManager.h>#import "WrapCpp_to_RN.h"
Gọi lớp Swift và các chức năng của nó
import React from 'react';
import {StyleSheet, Text, View, NativeModules, Button} from 'react-native';const App = () => {
const onPress = () => {
const {SendCpp_to_RN} = NativeModules;
SendCpp_to_RN.fromCpp((_err, res) => console.log(res));
};
return (
<View style={styles.container}>
<Text> Practice !</Text>
<Button title="C++ to React Native" color="#841584" onPress={onPress} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
Và chúng tôi đã hoàn tất, chỉ cần chạy ứng dụng
react-native run-ios
Hoặc chỉ cần nhấp vào nút “chạy” trên Xcode và xem những gì chúng tôi đã làm.
Tôi hy vọng bài viết của tôi hữu ích cho bạn, cảm ơn bạn đã dành thời gian đọc.
1656984600
今天,我继续分享我在 Native Module 和 C++ 方面的经验。
由于我们将看到很多为移动平台编写的 C/C++ 库,因此我们需要将它们实现到我们的 iOS 或 React Native 应用程序中。这就是为什么我想写一篇关于如何将一个函数从 C++ 导出到 React Native 的文章,它易于理解并且为初学者节省了时间。我将从一个新的 react native 应用程序开始
npx react-native init NativeModules
创建一个新的 C++ 文件并命名Cpp_to_RN.cpp
当我们创建一个新的 C++ 文件时,Xcode 会Cpp_to_RN.hpp
为我们创建一个头文件
首先,打开“ Cpp_to_RN.hpp
”文件,并创建一个包含没有主体的函数的类。
#ifndef Cpp_to_RN_hpp
#define Cpp_to_RN_hpp#include <stdio.h>
#include <string>class Cpp_to_RN {
public:
std::string sayHello();
};#endif /* Cpp_to_RN_hpp */
然后打开Cpp_to_RN.cpp
文件,写一个简单的函数“ sayHello()
”
#include "Cpp_to_RN.hpp"
std::string Cpp_to_RN::sayHello(){
return "Hello from CPP";
}
包装 C++ 文件并将它们导出到 IOS (swift) 端
一个。创建一个Objective C文件并命名Cpp_to_RN.m
重命名Cpp_to_RN.m
为 Cpp_to_RN.mm
湾。打开WrapCpp_to_RN.mm
文件并编写将包装sayHello
C++ 文件中的函数的正文内容。
#import <Foundation/Foundation.h>
#import "WrapCpp_to_RN.h"
#import "Cpp_to_RN.hpp"@implementation WrapCpp_to_RN- (NSString *) sayHello {
Cpp_to_RN fromCPP;
std::string helloWorldMessage = fromCPP.sayHello();
return [NSString
stringWithCString:helloWorldMessage.c_str()
encoding:NSUTF8StringEncoding];
}
@end
C。创建头文件并命名WrapCpp_to_RN.h
将函数导出wrapSayHello
到 Swift 文件
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
将 C++ 函数导出到 React Native
一个。创建一个 Swift 文件并命名SendCpp_to_RN.swift
注意:Xcode 会要求我们为我们创建一个NativeModules-Bridging-Header.h
文件。
创建一个类SendCpp_to_RN
并将其声明为NSObject
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
编写一个函数requiresMainQueueSetup()
来防止我们运行应用程序时出现警告
#import <Foundation/Foundation.h>
@interface WrapCpp_to_RN : NSObject
- (NSString *) wrapSayHello;
@end
编写一个函数来包装WrapCpp_to_RN()
fromWrapCpp_to_RN.mm
import Foundation@objc(SendCpp_to_RN)
class SendCpp_to_RN : NSObject {
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
@objc func fromCpp(_ successCallback: RCTResponseSenderBlock) -> Void {
successCallback([NSNull(), WrapCpp_to_RN().wrapSayHello() as Any])
}}
湾。将 Swift 文件中的包装函数导出到 React Native
创建一个 Objective C 文件以导出 Swift 类及其函数,使用Callback
#import <React/RCTBridgeModule.h>
#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"
@interface RCT_EXTERN_MODULE(SendCpp_to_RN, NSObject)RCT_EXTERN_METHOD(fromCpp:(RCTResponseSenderBlock)successCallback)@end
C。将 Swift 连接到 React Native,打开NativeModules-Bridging-Header.h
文件
#import <React/RCTBridgeModule.h>#import <React/RCTViewManager.h>#import "WrapCpp_to_RN.h"
调用 Swift 类及其函数
import React from 'react';
import {StyleSheet, Text, View, NativeModules, Button} from 'react-native';const App = () => {
const onPress = () => {
const {SendCpp_to_RN} = NativeModules;
SendCpp_to_RN.fromCpp((_err, res) => console.log(res));
};
return (
<View style={styles.container}>
<Text> Practice !</Text>
<Button title="C++ to React Native" color="#841584" onPress={onPress} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
我们完成了,只需运行应用程序
react-native run-ios
或者只需单击 Xcode 上的“运行”按钮,看看我们做了什么。
希望我的文章对您有所帮助,感谢您的阅读时间。