了解 Rails 与 webpacker 和在 JS 上的发生率
Understanding Rails with webpacker and incidence on JS
来自正在迁移的遗留应用程序的 rails 6 个应用程序调用:
<%= javascript_pack_tag 'zxing.js' %>
<script type="text/javascript">
window.addEventListener('load', function () {
let selectedDeviceId;
const codeReader = new ZXing.BrowserMultiFormatReader()
console.log('ZXing code reader initialized')
codeReader.listVideoInputDevices()
.then((videoInputDevices) => {
const sourceSelect = document.getElementById('sourceSelect')
selectedDeviceId = videoInputDevices[0].deviceId
if (videoInputDevices.length >= 1) {
videoInputDevices.forEach((element) => {
const sourceOption = document.createElement('option')
sourceOption.text = element.label
sourceOption.value = element.deviceId
sourceSelect.appendChild(sourceOption)
})
sourceSelect.onchange = () => {
selectedDeviceId = sourceSelect.value;
};
const sourceSelectPanel = document.getElementById('sourceSelectPanel')
sourceSelectPanel.style.display = 'block'
}
document.getElementById('startButton').addEventListener('click', () => {
codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
if (result) {
console.log(result)
document.getElementById('result').textContent = result.text
let formData = new FormData();
let CodeParams = {
code_data: result.text,
shopkeeper_id: <%= current_user.id %>
};
formData.append("code_json_data", JSON.stringify(CodeParams));
$.ajax({
url: "new_moviment",
type: "post",
data: formData,
processData: false,
contentType: false,
});
}
if (err && !(err instanceof ZXing.NotFoundException)) {
console.error(err)
document.getElementById('result').textContent = err
}
})
console.log(`Started continous decode from camera with id ${selectedDeviceId}`)
})
document.getElementById('resetButton').addEventListener('click', () => {
codeReader.reset()
document.getElementById('result').textContent = '';
console.log('Reset.')
})
})
.catch((err) => {
console.error(err)
})
})
正在加载 javascript,但页面的脚本不是 Uncaught ReferenceError: ZXing is not defined
ZXing documentation 确实根据 Use on browser with ES6 modules
或 AMD
、UMD
或 CommonJS
.[=32= 提供不同的代码库]
我的印象是,随着迁移到 webpacker,Rails 是在 ES6 下进行预处理。但这种印象被基于浏览器的代码和基于模块的代码这一事实所混淆。
应该如何编辑这个脚本(对于 JS-knotheads 来说,有没有在线工具可以识别和更改 ES6 的语法?)
更新
经过yarn add @zxing/library
packs/application.js编辑为
require("@zxing/library")
import("../src/qr_scan")
src/qr_scan.js现在如下:
import { BrowserMultiFormatReader, NotFoundException } from '@zxing/library';
window.addEventListener('load', function () {
let selectedDeviceId;
const codeReader = new BrowserMultiFormatReader() // note the updated module reference
console.log('ZXing code reader initialized')
codeReader.listVideoInputDevices()
.then((videoInputDevices) => {
const sourceSelect = document.getElementById('sourceSelect')
selectedDeviceId = videoInputDevices[0].deviceId
if (videoInputDevices.length >= 1) {
videoInputDevices.forEach((element) => {
const sourceOption = document.createElement('option')
sourceOption.text = element.label
sourceOption.value = element.deviceId
sourceSelect.appendChild(sourceOption)
})
sourceSelect.onchange = () => {
selectedDeviceId = sourceSelect.value;
};
const sourceSelectPanel = document.getElementById('sourceSelectPanel')
sourceSelectPanel.style.display = 'block'
}
document.getElementById('startButton').addEventListener('click', () => {
codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
if (result) {
console.log(result)
document.getElementById('result').textContent = result.text
let formData = new FormData();
let CodeParams = {
code_data: result.text
};
formData.append("code_json_data", JSON.stringify(CodeParams));
$.ajax({
url: 'new_user',
type: "post",
data: formData,
processData: false,
contentType: false,
});
}
if (err && !(err instanceof ZXing.NotFoundException)) {
console.error(err)
document.getElementById('result').textContent = err
}
})
console.log(`Started continous decode from camera with id ${selectedDeviceId}`)
})
document.getElementById('resetButton').addEventListener('click', () => {
codeReader.reset()
document.getElementById('result').textContent = '';
console.log('Reset.')
})
})
.catch((err) => {
console.error(err)
})
})
并且视图页面没有更多 javascript 引用。然而,加载页面会导致控制台出现以下错误:
Uncaught TypeError: _zxing_library__WEBPACK_IMPORTED_MODULE_0__.BrowserMultiFormatReader is not a constructor
指向 codeReader
行。该页面已通过 webpacker 尝试编译进行处理。
尽管 js/zxing-3544fb3b633f87715d29.js 528 KiB zxing [emitted] [immutable] zxing
已成功构建 ([./app/javascript/packs/zxing.js] 524 KiB {zxing} [built]
),但两个导入函数均失败:
ERROR in ./app/javascript/src/qr_scan.js 4:23-47
"export 'BrowserMultiFormatReader' was not found in '@zxing/library'
@ ./app/javascript/packs/application.js
ERROR in ./app/javascript/src/qr_scan.js 47:36-53
"export 'NotFoundException' was not found in '@zxing/library'
@ ./app/javascript/packs/application.js
在 zxing 编译文件中搜索这些字符串仅显示两个实例:
e.BrowserMultiFormatReader = s;
e.NotFoundException = l["default"];
自然导致控制台错误:
window.addEventListener('load', function () {
var selectedDeviceId;
var codeReader = new _zxing_library__WEBPACK_IMPORTED_MODULE_0__["BrowserMultiFormatReader"](); // note the updated module reference
当恢复到 library's documentation 引用的命令时,Webpacker 最终编译
const codeReader = new BrowserQRCodeReader() // note the updated module reference
// const codeReader = new BrowserMultiFormatReader() // note the updated module reference
但是现在,出现控制台错误:
Uncaught ReferenceError: BrowserQRCodeReader is not defined
指向var codeReader = new BrowserQRCodeReader();
JavaScript webpack 中的模块不会导出到全局范围,即,当将 Webpacker 与 Rails 一起使用时,您不能从 [=15] 中引用类似 ZXing
的内容=] 默认情况下在 ERB 模板中标记。
相反,您可以将所有 JavaScript 移动到 app/javascript
目录并更新您的 ZXing(和其他库)引用以使用模块导入。
Rails 会将“packs”文件夹中的所有内容视为一个单独的包。从指向您的源代码的应用程序包开始:
app/
javascript/
packs/
application.js
src/
my_barcode.js
// app/javascript/packs/application.js
import '../src/my_barcode'
// app/javascript/src/my_barcode.js
// Based off the module imports described in the ZXing README
import { BrowserMultiFormatReader, NotFoundException } from '@zxing/library/esm';
window.addEventListener('load', function () {
let selectedDeviceId;
const codeReader = new BrowserMultiFormatReader() // note the updated module reference
// and so on ...
并且在您的应用程序布局中:
<%= javascript_pack_tag 'application' %>
来自正在迁移的遗留应用程序的 rails 6 个应用程序调用:
<%= javascript_pack_tag 'zxing.js' %>
<script type="text/javascript">
window.addEventListener('load', function () {
let selectedDeviceId;
const codeReader = new ZXing.BrowserMultiFormatReader()
console.log('ZXing code reader initialized')
codeReader.listVideoInputDevices()
.then((videoInputDevices) => {
const sourceSelect = document.getElementById('sourceSelect')
selectedDeviceId = videoInputDevices[0].deviceId
if (videoInputDevices.length >= 1) {
videoInputDevices.forEach((element) => {
const sourceOption = document.createElement('option')
sourceOption.text = element.label
sourceOption.value = element.deviceId
sourceSelect.appendChild(sourceOption)
})
sourceSelect.onchange = () => {
selectedDeviceId = sourceSelect.value;
};
const sourceSelectPanel = document.getElementById('sourceSelectPanel')
sourceSelectPanel.style.display = 'block'
}
document.getElementById('startButton').addEventListener('click', () => {
codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
if (result) {
console.log(result)
document.getElementById('result').textContent = result.text
let formData = new FormData();
let CodeParams = {
code_data: result.text,
shopkeeper_id: <%= current_user.id %>
};
formData.append("code_json_data", JSON.stringify(CodeParams));
$.ajax({
url: "new_moviment",
type: "post",
data: formData,
processData: false,
contentType: false,
});
}
if (err && !(err instanceof ZXing.NotFoundException)) {
console.error(err)
document.getElementById('result').textContent = err
}
})
console.log(`Started continous decode from camera with id ${selectedDeviceId}`)
})
document.getElementById('resetButton').addEventListener('click', () => {
codeReader.reset()
document.getElementById('result').textContent = '';
console.log('Reset.')
})
})
.catch((err) => {
console.error(err)
})
})
正在加载 javascript,但页面的脚本不是 Uncaught ReferenceError: ZXing is not defined
ZXing documentation 确实根据 Use on browser with ES6 modules
或 AMD
、UMD
或 CommonJS
.[=32= 提供不同的代码库]
我的印象是,随着迁移到 webpacker,Rails 是在 ES6 下进行预处理。但这种印象被基于浏览器的代码和基于模块的代码这一事实所混淆。
应该如何编辑这个脚本(对于 JS-knotheads 来说,有没有在线工具可以识别和更改 ES6 的语法?)
更新
经过yarn add @zxing/library
packs/application.js编辑为
require("@zxing/library")
import("../src/qr_scan")
src/qr_scan.js现在如下:
import { BrowserMultiFormatReader, NotFoundException } from '@zxing/library';
window.addEventListener('load', function () {
let selectedDeviceId;
const codeReader = new BrowserMultiFormatReader() // note the updated module reference
console.log('ZXing code reader initialized')
codeReader.listVideoInputDevices()
.then((videoInputDevices) => {
const sourceSelect = document.getElementById('sourceSelect')
selectedDeviceId = videoInputDevices[0].deviceId
if (videoInputDevices.length >= 1) {
videoInputDevices.forEach((element) => {
const sourceOption = document.createElement('option')
sourceOption.text = element.label
sourceOption.value = element.deviceId
sourceSelect.appendChild(sourceOption)
})
sourceSelect.onchange = () => {
selectedDeviceId = sourceSelect.value;
};
const sourceSelectPanel = document.getElementById('sourceSelectPanel')
sourceSelectPanel.style.display = 'block'
}
document.getElementById('startButton').addEventListener('click', () => {
codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
if (result) {
console.log(result)
document.getElementById('result').textContent = result.text
let formData = new FormData();
let CodeParams = {
code_data: result.text
};
formData.append("code_json_data", JSON.stringify(CodeParams));
$.ajax({
url: 'new_user',
type: "post",
data: formData,
processData: false,
contentType: false,
});
}
if (err && !(err instanceof ZXing.NotFoundException)) {
console.error(err)
document.getElementById('result').textContent = err
}
})
console.log(`Started continous decode from camera with id ${selectedDeviceId}`)
})
document.getElementById('resetButton').addEventListener('click', () => {
codeReader.reset()
document.getElementById('result').textContent = '';
console.log('Reset.')
})
})
.catch((err) => {
console.error(err)
})
})
并且视图页面没有更多 javascript 引用。然而,加载页面会导致控制台出现以下错误:
Uncaught TypeError: _zxing_library__WEBPACK_IMPORTED_MODULE_0__.BrowserMultiFormatReader is not a constructor
指向 codeReader
行。该页面已通过 webpacker 尝试编译进行处理。
尽管 js/zxing-3544fb3b633f87715d29.js 528 KiB zxing [emitted] [immutable] zxing
已成功构建 ([./app/javascript/packs/zxing.js] 524 KiB {zxing} [built]
),但两个导入函数均失败:
ERROR in ./app/javascript/src/qr_scan.js 4:23-47
"export 'BrowserMultiFormatReader' was not found in '@zxing/library'
@ ./app/javascript/packs/application.js
ERROR in ./app/javascript/src/qr_scan.js 47:36-53
"export 'NotFoundException' was not found in '@zxing/library'
@ ./app/javascript/packs/application.js
在 zxing 编译文件中搜索这些字符串仅显示两个实例:
e.BrowserMultiFormatReader = s;
e.NotFoundException = l["default"];
自然导致控制台错误:
window.addEventListener('load', function () {
var selectedDeviceId;
var codeReader = new _zxing_library__WEBPACK_IMPORTED_MODULE_0__["BrowserMultiFormatReader"](); // note the updated module reference
当恢复到 library's documentation 引用的命令时,Webpacker 最终编译
const codeReader = new BrowserQRCodeReader() // note the updated module reference
// const codeReader = new BrowserMultiFormatReader() // note the updated module reference
但是现在,出现控制台错误:
Uncaught ReferenceError: BrowserQRCodeReader is not defined
指向var codeReader = new BrowserQRCodeReader();
JavaScript webpack 中的模块不会导出到全局范围,即,当将 Webpacker 与 Rails 一起使用时,您不能从 [=15] 中引用类似 ZXing
的内容=] 默认情况下在 ERB 模板中标记。
相反,您可以将所有 JavaScript 移动到 app/javascript
目录并更新您的 ZXing(和其他库)引用以使用模块导入。
Rails 会将“packs”文件夹中的所有内容视为一个单独的包。从指向您的源代码的应用程序包开始:
app/
javascript/
packs/
application.js
src/
my_barcode.js
// app/javascript/packs/application.js
import '../src/my_barcode'
// app/javascript/src/my_barcode.js
// Based off the module imports described in the ZXing README
import { BrowserMultiFormatReader, NotFoundException } from '@zxing/library/esm';
window.addEventListener('load', function () {
let selectedDeviceId;
const codeReader = new BrowserMultiFormatReader() // note the updated module reference
// and so on ...
并且在您的应用程序布局中:
<%= javascript_pack_tag 'application' %>