添加样式表
级联样式表是任何前端用户界面的重要组成部分。 默认启动器配置为导入可以编辑的 main.css 文件,但您可能更喜欢将样式表导入 JavaScript 文件,或者使用替代格式,例如 Syntactically Awesome Style Sheets,又名 SCSS。
本教程通过逐步构建联系人 dapp 来说明如何配置 webpack 以导入样式表。
如果您已经知道如何将级联样式表 (CSS) 添加到基于 webpack 的项目中,则可以跳过本教程。
| 本教程说明了使用 React 框架来管理前端的文档对象模型 (DOM)。 因为 React 有自己的自定义 DOM 语法,所以需要修改 webpack 配置来编译前端代码,前端代码是用 JSX 编写的。 有关学习使用 React 和 JSX 的更多信息,请参见 React 网站 上的Getting started。 |
创建一个新项目
为您的自定义前端 dapp 创建一个新项目目录:
-
如果您还没有打开一个终端外壳,请在您的本地计算机上打开一个终端外壳。
-
更改为您用于 Internet Computer 项目的文件夹(如果您正在使用一个)。
-
如有必要,请验证您是否在本地安装了
node.js。 -
通过运行以下命令创建一个新项目:
dfx new contacts -
通过运行以下命令切换到您的项目目录:
cd contacts
安装 React 框架
如果您以前从未使用过 React,您可能想探索Intro to React 教程或React website 在编辑前端代码之前。
要安装所需的框架模块:
-
通过运行以下命令安装 React 模块:
npm install --save react react-dom -
通过运行以下命令安装所需的 TypeScript 语言编译器加载程序:
npm install --save-dev typescript ts-loader -
通过运行以下命令安装所需的样式加载器:
npm install --save-dev style-loader css-loader如果
npm install命令报告了漏洞,您可能还需要运行npm audit fix命令来尝试修复报告的漏洞,然后再继续。作为安装这些模块的替代方法,您可以编辑默认的 package.json文件来为您的项目添加依赖项。{ "name": "contacts_assets", "version": "0.1.0", "description": "", "keywords": [], "scripts": { "build": "webpack" }, "devDependencies": { "assert": "2.0.0", "buffer": "6.0.3", "css-loader": "^5.2.1", "events": "3.3.0", "html-webpack-plugin": "5.3.1", "process": "0.11.10", "stream-browserify": "3.0.0", "style-loader": "^2.0.0", "terser-webpack-plugin": "5.1.1", "ts-loader": "^8.1.0", "typescript": "^4.2.4", "util": "0.12.3", "webpack-cli": "4.5.0", "webpack": "5.24.4" }, "dependencies": { "@dfinity/agent": "0.10.0", "@dfinity/candid": "0.10.0", "@dfinity/principal": "0.10.0", "react-dom": "^17.0.2", "react": "^17.0.2" } }此示例
package.json文件中的 JavaScript 代理版本为0.10.0。 但是,在大多数情况下,您会希望使用可用的最新版本的代理。 当您创建一个新项目时,dfx new命令会自动为您检索最新版本的 JavaScript 代理。 您还可以在创建项目后通过运行npm install --save @dfinity/agent命令手动检索最新版本。
修改默认程序
对于本教程,您将使用允许您存储和查找联系信息的代码修改主程序。
修改默认程序:
-
在文本编辑器中打开
src/contacts/main.mo文件并删除现有内容。 -
将以下示例代码复制并粘贴到文件中:
import List "mo:base/List"; import AssocList "mo:base/AssocList"; actor Contact { var contacts : ContactsMap = List.nil(); type Name = Text; type Phone = Nat; type Entry = { name : Name; address1 : Text; address2 : Text; email : Text; phone : Phone; }; type ContactsMap = AssocList.AssocList<Name, Entry>; func nameEq(lhs : Name, rhs : Name) : Bool { return lhs == rhs; }; public func insert(name : Name, address1 : Text, address2 : Text, email : Text, phone : Phone) : async () { let newEntry : Entry = { name; address1; address2; email; phone; }; let (newContacts, _) = AssocList.replace( contacts, name, func(n: Name, m: Name) : Bool { n == m }, ?newEntry ); contacts := newContacts; }; public query func lookup(name : Name) : async ?Entry { return AssocList.find(contacts, name, nameEq); }; }; -
保存更改并关闭
main.mo文件以继续。
修改前端文件
您现在已准备好为您的程序创建一个新的前端。
-
在文本编辑器中打开 webpack 配置文件(
webpack.config.js)。 -
修改前端入口,将默认的 index.html 替换为 index.jsx。
entry: { // The frontend.entrypoint points to the HTML file for this build, so we need // to replace the extension to `.js`. index: path.join(__dirname, asset_entry).replace(/\.html$/, ".jsx"), }, -
在
plugins部分上方找到module键的注释示例,然后取消注释以下行:module: { rules: [ { test: /\.(js|ts)x?$/, loader: "ts-loader" }, { test: /\.css$/, use: ['style-loader','css-loader'] } ] }, -
这些设置使您的程序能够使用
ts-loader编译器并导入 CSS 文件。如果你想添加对 .scss或.sass文件的支持,你应该安装sass-loader:npm install --save react react-dom然后在
+webpack.config.js中的 `+css-loader url 下面添加这个附加规则:module: { rules: [ // ... { test: /\.s[ac]ss$/i, use: [ // Creates `style` nodes from JS strings "style-loader", // Translates CSS into CommonJS "css-loader", // Compiles Sass to CSS "sass-loader", ], }, ] }, -
保存更改并关闭
webpack.config.js文件以继续。 -
在项目的根目录中创建一个名为
tsconfig.json的新文件。 -
在文本编辑器中打开
tsconfig.json文件,然后将以下内容复制并粘贴到文件中:{ "compilerOptions": { "target": "es2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "lib": ["ES2018", "DOM"], /* Specify library files to be included in the compilation. */ "allowJs": true, /* Allow javascript files to be compiled. */ "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ }, "include": ["src/**/*"], } -
保存更改并关闭
tsconfig.json文件以继续。
为您的项目添加样式表
您现在已准备好创建一个新的级联样式表并将其添加到您的项目中。
添加样式表:
-
切换到
src/contacts_assets/assets目录。cd src/contacts_assets/assets/ -
在文本编辑器中打开
main.css文件并删除现有内容。 -
为前端定义一些样式属性。
例如,将以下示例样式复制并粘贴到文件中:
html { background-color: bisque; } body { font-family: Arial, Helvetica, sans-serif; display: block; margin: 10px; } h1 { color: darkblue; font-size: 32px; } div.new-entry { margin: 30px 20px 30px 20px; } .new-entry > div { margin-bottom: 15px; } table { margin-top: 12px; border-top: 1px solid darkblue; border-bottom: 1px solid darkblue; } #form { margin: 30px 0 30px 20px; } button { line-height: 20px; } #lookupName { margin-right: 12px; } -
保存更改并关闭
+main.css文件以继续。 -
切换到
+src/contacts assets/src目录。cd ../src -
在文本编辑器中打开默认的
index.js文件并删除现有内容。 -
将以下示例代码复制并粘贴到
index.js文件中:import * as React from "react"; import { render } from "react-dom"; import { contacts } from "../../declarations/contacts"; import "../assets/mycontacts.css"; const Contact = () => { async function doInsert() { let name = document.getElementById("newEntryName").value; let add1 = document.getElementById("newEntryAddress1").value; let add2 = document.getElementById("newEntryAddress2").value; let email = document.getElementById("newEntryEmail").value; let phone = document.getElementById("newEntryPhone").value; contacts.insert(name, add1, add2, email, parseInt(phone, 10)); } async function lookup() { let name = document.getElementById("lookupName").value; contacts.lookup(name).then((opt_entry) => { let entry; if (opt_entry.length == 0) { entry = { name: "", description: "", phone: "" }; } else { entry = opt_entry[0]; } document.getElementById("newEntryName").value = entry.name; document.getElementById("newEntryAddress1").value = entry.address1; document.getElementById("newEntryAddress2").value = entry.address2; document.getElementById("newEntryEmail").value = entry.email; document.getElementById("newEntryPhone").value = entry.phone.toString(); }); } return ( <div className="new-entry"> <h1>My Contacts</h1> <div> Add or update contact information: <form id="contact"> <table> <tbody> <tr> <td>Name:</td> <td> <input id="newEntryName"></input> </td> </tr> <tr> <td>Address 1 (street):</td> <td> <input id="newEntryAddress1"></input> </td> </tr> <tr> <td>Address 2 (city and state):</td> <td> <input id="newEntryAddress2"></input> </td> </tr> <tr> <td>Email:</td> <td> <input id="newEntryEmail"></input> </td> </tr> <tr> <td>Phone:</td> <td> <input id="newEntryPhone" type="number"></input> </td> </tr> </tbody> </table> </form> </div> <div> <button onClick={() => doInsert()}>Add Contact</button> </div> <div> Lookup name:{" "} <input id="lookupName" style={{ lineHeight: "20px" }}></input> <button onClick={() => lookup()}>Lookup</button> </div> </div> ); }; document.title = "DFINITY CONTACT EXAMPLE"; render(<Contact />, document.getElementById("contacts")); -
通过运行以下命令将修改后的
index.js文件重命名为index.jsx:mv index.js index.jsx -
在文本编辑器中打开默认的
src/contacts_assets/src/index.html文件,然后删除main.css链接并使用<div id="contacts"></div> 更新 `body内容 `。例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /> <title>contacts</title> <base href="/" /> </head> <body> <main> <div id="contacts"></div> </main> </body> </html> -
返回项目根目录,如:
cd ../../..
启动本地网络
在构建 contacts 项目之前,您需要连接到本地容器执行环境。
在本地启动环境:
-
在本地计算机上打开一个新的终端窗口或选项卡。
-
通过运行以下命令在本地计算机上启动本地容器执行环境:
dfx start --background环境完成启动操作后,您可以继续下一步。
注册、构建和部署 dapp
在开发环境中连接到本地容器执行环境后,您可以注册、构建和部署 dapp 以进行测试。
部署 dapp:
-
如果需要,请检查您是否仍在项目的根目录中。
-
通过运行以下命令注册、构建和部署您的 dapp:
dfx deploydfx deploy命令输出显示有关它执行的操作的信息。请记住,因为您在本地运行容器执行环境,所以当您运行
dfx deploy命令时显示的标识符仅在您的计算机上有效。要在 Internet Computer platform 上部署容器,您必须使用
--network命令行选项指定要部署到 Internet Computer 而不是本地环境:dfx deploy --network=ic -
启动 Webpack 开发服务器:
npm start
查看前端
您现在可以访问 contacts dapp 的前端。
查看前端:
-
打开浏览器访问“http://localhost:8080”。
-
验证是否使用 My Contacts 表单提示您。
例如:

-
通过在姓名、地址和电子邮件输入字段中输入文本并在电话输入字段中输入数字,然后单击*添加联系人*,创建一个或多个测试记录。
-
清除表单字段并在查找姓名字段中键入联系人姓名,然后单击*查找*以查看存储的联系人信息。
请记住,您键入的 查找名称 必须与您添加的联系人姓名完全匹配。
修改样式表并测试您的更改
查看联系人 dapp 后,您可能需要进行一些更改。
要更改样式表属性:
src/contacts_assets/assets/mycontacts.css 文件并修改其样式设置。+ 例如,您可能想要更改输入表单的背景颜色或样式。
+ 您应该会在打开的浏览器窗口中立即看到更改更新。