添加样式表
级联样式表是任何前端用户界面的重要组成部分。 默认启动器配置为导入可以编辑的 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 deploy
dfx 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
文件并修改其样式设置。+ 例如,您可能想要更改输入表单的背景颜色或样式。
+ 您应该会在打开的浏览器窗口中立即看到更改更新。