gpt4 book ai didi

javascript - 如何使用 Elm 和 Webpack 读取文本文件

转载 作者:行者123 更新时间:2023-11-29 23:23:58 24 4
gpt4 key购买 nike

我用 Elm 编写了一个简单的测验应用程序。正如教程中所解释的那样,在 Elm 中访问外部文件的唯一方法是通过 Javascript 使用端口。所以我在我的 Elm 文件中包含了端口,现在我必须将它们添加到用作入口点的 index.js 文件中。我使用 webpack 构建完整的应用程序。
但是,我不明白 webpack 逻辑。这是我的文件树:

resources
|---- images
|---- questions
|---- question_1.txt
|---- question_2.txt
|---- ...
|---- scores
|---- scores_table.json
src
|---- MyElm.elm
|---- Questions.elm
|---- index.js
|---- index.html

webpack.config.js

我的 JS 组件需要读取 questions 文件夹中所有可能的问题,以确定问题总数并通过端口将它们提供给 Elm。同理,JS组件需要解析scores_table.json文件,将结果发送给Elm应用。

我可以在我的 index.js 应用程序中使用什么来读取这些文件?我尝试使用 require,但我认为我没有正确使用它。

这是我在 Stack Overflow 上的第一个问题,所以如果有任何遗漏,请告诉我。

最小示例

这是我所拥有的简化版本:

webpack.config.js

var path = require("path");

module.exports = {
entry: {
app: [
'./src/index.js'
]
},

output: {
path: path.resolve(__dirname + '/dist'),
filename: '[name].js',
},

module: {
rules: [
{
test: /\.txt$/,
use: 'raw-loader'
},
{
test: /\.(css|scss)$/,
loaders: [
'style-loader',
'css-loader',
]
},
{
test: /\.html$/,
exclude: /node_modules/,
loader: 'file-loader?name=[name].[ext]',
},
{
test: /\.elm$/,
exclude: [/elm-stuff/, /node_modules/],
loader: 'elm-webpack-loader?verbose=true&warn=true',
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff',
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader',
},
],

noParse: /\.elm$/,
},

devServer: {
inline: true,
stats: { colors: true },
},

};

index.js

const RESOURCES_DIR = "../resources/";
const IMAGES_DIR = RESOURCES_DIR + "images/"
const QUESTIONS_DIR = RESOURCES_DIR + "questions/"
const SCORES_DIR = RESOURCES_DIR + "scores/"

require("./index.html");
const scores_table =
require(SCORES_DIR + "scores_table.json");

var total_question_nb = 0;
var questions_table = [];
var end = false;

while (!end) {
try {
data = require(
"raw!" +
QUESTIONS_DIR +
"question_${total_question_nb}.txt");
questions_table.push(data);
total_question_nb += 1;
} catch (e) {
end = true;
}
}

console.log(questions_table[0]);
console.log(total_question_nb);

var Elm = require("./MyElm.elm");
var mountNode = document.getElementById("elm-app");

var app = Elm.MyElm.embed(mountNode);

// Need to add port gestion there

MyElm.elm

...
import Questions
...

问题.elm

...
-- (current_question_no, ans_id)
port ask_question_score : (Int, Int) -> Cmd msg

-- next_question_no
port ask_next_question : Int -> Cmd msg

-- question_score
port receive_question_score : (List Int -> msg) -> Sub msg

-- (next_question_no, total_question_nb, next_question_text)
port receive_next_question : ((Int, Int, String) -> msg) -> Sub msg

-- ()
port receive_end_question : (() -> msg) -> Sub msg
...

这是我使用 Webpack 加载页面时得到的结果:

Uncaught Error: Cannot find module "../resources/scores/scores_table.json".
at r (app.js:1)
at Object.<anonymous> (app.js:1)
at r (app.js:1)
at Object.<anonymous> (app.js:1)
at r (app.js:1)
at app.js:1
at app.js:1

最佳答案

TLDR 您需要设置 Webpack 的 code splitting with dynamic imports启用动态 require

Webpack 旨在将所有源文件压缩到一个“构建”文件中。当然,这取决于识别您要导入的文件。当您将表达式而不是纯字符串传递给 require 时,webpack 可能无法正确识别您想要的文件。

为了明确告诉 webpack 要包含什么,您可以使用“动态”导入,即 code splitting .我会说代码拆分是相当高级的,如果你想避免它,只需对要导入的文件进行硬编码即可。如果文件不经常更改,那应该没问题。


例子

如果你知道文件名:

const scores = require('../resources/scores/scores_table.json')
// or
import scores from '../resources/scores/scores_table.json'

// The `import()` function could be used here, but it returns a Promise
// I believe `require()` is blocking, which is easier to deal with here
// (though not something I'd want in a production application!)
const questions = [
require('../resources/questions/question_1.txt'),
require('../resources/questions/question_2.txt'),
]

如果你想动态导入文件(就像你可能会做的问题):

// Utility function
// Example:
// arrayOfLength(4) -> [0, 1, 2, 3]
const arrayOfLength = length =>
(new Array(length)).fill(0).map((val, i) => i)

const questionsCount = 100 // <- You need to know this beforehand

// This would import questions "question_0.txt" through "question_99.txt"
const questionPromises = arrayOfLength(questionsCount)
.map(i =>
import(`../resources/questions/question_${i}.txt`)
.catch(error => {
// This allows other questions to load if one fails
console.error('Failed to load question ' + i, error)
return null
})
)

Promise.all(questionPromises)
.then(questions => { ... })

对于动态导入,您需要处理 promise 。您还可以使用 async/await 使其看起来更好一些(并非所有浏览器都支持 - 需要设置转译)


如果文件确实经常更改,这意味着您经常修改问题和/或分数表,您可能应该使用数据库而不是动态导入。

关于javascript - 如何使用 Elm 和 Webpack 读取文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49840016/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com