添加parcel 到cdh
在上一篇文章中,我们遇到了Hyperapp,这是一个微型库,可用于以类似于React或Vue的方式构建动态的单页Web应用程序。
在这篇文章中,我们将把事情提高一个档次。 我们将在本地创建该应用程序(之前我们在CodePen上进行过开发),了解如何使用Parcel (类似于webpack或Rollup的模块捆绑器)捆绑该应用程序,并使用GitHub Pages将其部署到Web 上 。
如果您没有从第一篇文章中完成该项目,请不要担心。 这里提供了所有代码(尽管我不会详细解释它的作用),并且所概述的原理可以应用于大多数其他JavaScript项目。
如果您想了解我们将要完成的工作,可以在此处查看完成的项目 ,或从GitHub repo下载代码。
基本设定
为了进行后续操作,您需要同时安装Node.js和npm (它们打包在一起)。 我建议使用诸如nvm之类的版本管理器来管理Node的安装( 方法如下 ),如果您希望获得有关npm的帮助,请查看我们的初学者友好型npm教程 。
我们将使用终端命令来创建文件和文件夹,但是如果您要这么做,只需指向并单击即可。
首先,创建一个名为hyperlist
的新文件夹:
mkdir hyperlist
现在转到该目录并使用npm初始化一个新项目:
cd hyperlist/
npm init
这将提示您回答有关该应用程序的一些问题。 只需按Enter即可接受其中任何一种的默认设置,但可以随意添加您的作者姓名并添加应用程序描述。
这应该在hyperlist
目录中创建一个名为package.json
的文件,其外观类似于以下内容:
{
"name": "hyperlist",
"version": "1.0.0",
"description": "A To-do List made with Hyperapp",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "DAZ",
"license": "MIT"
}
现在,我们需要安装Hyperapp库。 这是使用npm和--save
标志一起完成的,这意味着package.json
文件将被更新为包括它作为依赖项:
npm install --save hyperapp
这可能会发出有关没有存储库字段的警告。 不用担心,我们稍后将修复它。 它应该更新package.json
文件以包括以下条目(版本号可能会稍有不同):
"dependencies": {
"hyperapp": "^1.2.5"
}
它还将创建一个名为node_modules
的目录,其中存储了所有Hyperapp文件,以及一个名为package-lock.json
的文件。 这用于跟踪使用npm安装的所有软件包的依赖关系树。
现在我们准备开始创建该应用程序!
资料夹结构
通常将所有源代码放入名为src
的文件夹中。 在该文件夹中,我们将所有JavaScript文件放入一个名为js
的目录中。 让我们现在创建两个:
mkdir -p src/js
在上一篇文章中,我们了解到应用程序是在Hyperapp中构建的,它包含三个主要部分:状态,操作和视图。 为了代码组织的利益,我们将每个部分的代码放在单独的文件中,因此我们需要在js
目录中创建以下文件:
cd src/js
touch state.js actions.js view.js
不用担心它们都空着。 我们将尽快添加代码!
最后,我们将回到src
目录并创建我们的“入口点”文件。 这些是将链接到所有其他文件的文件。 第一个是index.html
,它将包含一些基本HTML,另一个是index.js
,它将链接到我们所有其他JavaScript文件以及我们的SCSS文件:
cd ..
touch index.html index.js
现在我们的文件夹结构已经就绪,我们可以继续添加一些代码并将所有文件连接在一起。 向前!
一些基本HTML
![](https://i-blog.csdnimg.cn/blog_migrate/984c27c3d0953e923806932d8c4d97ae.png)
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
我们将从在index.html
文件中添加一些基本HTML代码开始。 Hyperapp负责创建HTML,并可以将其直接呈现到<body>
标签中。 这意味着我们只需要设置<head>
标记中包含的元信息。 除了<title>
标记的值之外,您可以为每个项目使用相同的index.html
文件。 在您喜欢的文本编辑器中打开index.html
并添加以下代码:
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>HyperList</title>
</head>
<body>
<script src='index.js'></script>
</body>
</html>
现在是时候添加一些JavaScript代码了!
ES6模块
ES6(又称ES2015)中引入了本机JavaScript模块 。 不幸的是,尽管现在情况开始有所改善 ,但浏览器在本地采用ES6模块的速度一直很慢。 幸运的是,我们仍然可以使用它们来组织我们的代码,Parcel将整理出将它们拼凑在一起的方式。
让我们从在state.js
文件中添加初始状态的代码开始:
const state = {
items: [],
input: '',
placeholder: 'Make a list..'
};
export default state;
这与我们在上一篇文章中使用的对象相同,但是最后有export
声明。 这将使该对象可用于导入它的任何其他文件。 通过将其设置为默认导出,我们以后再导入时不必显式命名它。
接下来,我们将动作添加到actions.js
:
const actions = {
add: () => state => ({
input: '',
items: state.items.concat({
value: state.input,
completed: false,
id: Date.now()
})
}),
input: ({ value }) => ({ input: value }),
toggle: id => state => ({
items: state.items.map(item => (
id === item.id ? Object.assign({}, item, { completed: !item.completed }) : item
))
}),
destroy: id => state => ({
items: state.items.filter(item => item.id !== id)
}),
clearAllCompleted: ({ items }) => ({
items: items.filter(item => !item.completed)
})
};
export default actions;
同样,这与我们在上一篇文章中使用的对象相同,并在末尾添加了export
声明。
最后,我们将视图代码添加到view.js
:
import { h } from 'hyperapp'
const AddItem = ({ add, input, value, placeholder }) => (
<div class='flex'>
<input
type="text"
onkeyup={e => (e.keyCode === 13 ? add() : null)}
oninput={e => input({ value: e.target.value })}
value={value}
placeholder={placeholder}
/>
<button onclick={add}>+</button>
</div>
);
const ListItem = ({ value, id, completed, toggle, destroy }) => (
<li class={completed && "completed"} id={id} key={id} onclick={e => toggle(id)}>
{value} <button onclick={ () => destroy(id) }>x</button>
</li>
);
const view = (state, actions) => (
<div>
<h1><strong>Hyper</strong>List</h1>
<AddItem
add={actions.add}
input={actions.input}
value={state.input}
placeholder={state.placeholder}
/>
<ul id='list'>
{state.items.map(item => (
<ListItem
id={item.id}
value={item.value}
completed={item.completed}
toggle={actions.toggle}
destroy={actions.destroy}
/>
))}
</ul>
<button onclick={() => actions.clearAllCompleted({ items: state.items }) }>
Clear completed items
</button>
</div>s
);
export default view;
首先,此文件使用import
声明从我们之前使用npm安装的Hyperapp库中导入h
模块。 Hyperapp使用此功能来创建构成视图的虚拟DOM节点。
该文件包含两个组件: AddItem
和ListItem
。 这些只是返回JSX代码的函数,用于将视图的不同部分抽象为单独的构建块。 如果发现正在使用大量组件,则可能值得将它们移动到单独的components.js
文件中,然后将其导入到view.js
文件中。
请注意,仅view
函数在文件末尾导出。 这意味着只能由其他文件而不是单独的组件导入此功能。
现在,我们已经添加了所有JavaScript代码,我们只需要将它们全部整合到index.js
文件中即可。 这是使用import
指令完成的。 将以下代码添加到index.js
:
import { app } from 'hyperapp'
import state from './js/state.js'
import actions from './js/actions.js'
import view from './js/view.js'
const main = app(state, actions, view, document.body);
这将从Hyperapp库中导入app
函数,然后导入我们刚创建的三个JavaScript文件。 从这些文件中的每个文件导出的对象或函数分别分配给变量state
, actions
和view
,因此可以在此文件中引用它们。
代码的最后一行调用app
函数,该函数将启动应用程序运行。 它使用从导入文件中创建的每个变量作为前三个参数。 最后一个参数是将在其中呈现应用程序HTML元素-按照惯例,它是document.body
。
添加一些样式
在继续构建我们的应用程序之前,我们应该给它一些样式。 让我们转到src
目录并为SCSS创建一个文件夹:
mkdir src/scss
现在,我们将创建两个文件,其中将包含在第1部分中使用的SCSS代码:
cd src/scss
touch index.scss _settings.scss
我们正在使用一个名为_settings.scss
的文件来存储应用程序将使用的不同字体和颜色的所有Sass变量。 如果您将来决定更新任何这些值,这将使他们更容易找到。 打开_settings.scss
文件并添加以下代码:
// fonts
@import url("https://fonts.googleapis.com/css?family=Racing+Sans+One");
$base-fonts: Helvetica Neue, sans-serif;
$heading-font: Racing Sans One, sans-serif;
// colors
$primary-color: #00caff;
$secondary-color: hotpink;
$bg-color: #222;
特定于应用程序CSS放在index.scss
,但是我们需要确保在开始时导入_settings.scss
文件,因为其中包含的变量稍后会在文件中引用。 打开index.scss
并添加以下代码:
@import 'settings';
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
padding-top: 50px;
background: $bg-color;
color: $primary-color;
display: flex;
height: 100vh;
justify-content: center;
font-family: $base-fonts;
}
h1 {
color: $secondary-color;
& strong{ color: $primary-color; }
font-family: $heading-font;
font-weight: 100;
font-size: 4.2em;
text-align: center;
}
a{ color: $primary-color; }
.flex{
display: flex;
align-items: top;
margin: 20px 0;
input {
border: 1px solid $primary-color;
background-color: $primary-color;
font-size: 1.5em;
font-weight: 200;
width: 50vw;
height: 62px;
padding: 15px 20px;
margin: 0;
outline: 0;
&::-webkit-input-placeholder { color: $bg-color; }
&::-moz-placeholder { color: $bg-color; }
&::-ms-input-placeholder { color: $bg-color; }
&:hover, &:focus, &:active { background: $primary-color; }
}
button {
height: 62px;
font-size: 1.8em;
padding: 5px 15px;
margin: 0 3px;
}
}
ul#list {
display: flex;
flex-direction: column;
padding: 0;
margin: 1.2em;
width: 50vw;
li {
font-size: 1.8em;
vertical-align: bottom;
&.completed{
color: $secondary-color;
text-decoration: line-through;
button{
color: $primary-color;
}
}
button {
background: none;
border: none;
color: $secondary-color;
outline: none;
font-size: 0.8em;
font-weight: 50;
padding-top: 0.3em;
margin-left: 5px;
}
}
}
button {
background: $bg-color;
border-radius: 0px;
border: 1px solid $primary-color;
color: $primary-color;
font-weight: 100;
outline: none;
padding: 5px;
margin: 0;
&:hover, &:disabled {
background: $primary-color;
color: #111;
}
&:active { outline: 2px solid $primary-color; }
&:focus { border: 1px solid $primary-color; }
}
如果您的SCSS开始变得更加复杂,则可以将其分解为单独的文件,然后将它们全部导入index.scss
。
现在,我们需要将这些文件链接到我们的应用程序。 实际上,我们并不像通常使用CSS那样将链接放在HTML文件中。 相反,我们将其放置在index.js
文件中。 这是因为我们正在使用SCSS,并且需要将其预处理为CSS。 Parcel将为我们做到这一点,还可以将HTML文件链接到它创建的标准CSS文件。
要导入SCSS文件,我们只需要更新index.js
文件以包括以下行:
import './scss/index.scss'
既然我们所有的代码都已完成,现在是时候开始构建过程了!
巴别塔
Babel会将现代JavaScript代码转换为大多数浏览器可以使用的代码。 它还将负责将JSX代码重写为纯JavaScript。
为了能够将Babel与JSX转换一起使用,我们需要将其与JSX插件一起安装:
npm install --save babel-plugin-transform-react-jsx babel-preset-env
我们还需要创建一个.babel.rc
文件,该文件用于告诉Babel在处理JSX时使用Hyperapp中的h
函数。 以下代码将使用相关信息创建文件:
echo '{ "plugins": [["transform-react-jsx", { "pragma": "h" }]] }' > .babelrc
请注意,这是一个隐藏文件 ,因此创建后您可能看不到它!
包
不幸的是,我们的代码目前无法在所有浏览器中正常运行。 我们需要使用构建过程将ES6 +代码转换为ES5,并将所有JS文件合并为一个文件。 让我们使用包裹来做到这一点。
Parcel是一个模块捆绑器,类似于webpack或Rollup,它可以实现零配置,并且速度非常快。 它使我们可以在单独的文件中编写现代JavaScript,然后将它们捆绑到一个最小JavaScript文件中,大多数浏览器都可以使用。 它也支持开箱即用的多个CSS,SCSS和PostCSS文件。
首先,让我们安装Parcel:
npm install --save parcel-bundler
Parcel带有自己的内置服务器。 这意味着您可以继续开发并更改应用程序,Parcel将在后台构建它,因此任何更改都会立即显示!
要启动服务器运行,请输入以下命令:
./node_modules/.bin/parcel src/index.html --out-dir docs
这指定入口点是index.html
文件。 这就是Parcel需要知道的所有事情,因为它将遵循该文件中index.js
的链接,然后遵循该文件中的import
指令。
它还指定使用一个名为docs
的文件夹将所有静态文件输出到该文件夹。 默认情况下,通常将其称为dist
但是,正如您稍后将看到的,我们需要将其称为docs
以便我们可以将其与GitHub Pages集成。
您还应该在终端窗口中看到一条消息,指出正在构建该应用程序。 您甚至可能会注意到,Parcel为您安装了npm模块node-sass
,因为它会自动注意到我们一直在使用SCSS文件,但是我们没有安装node-sass
。 多么酷啊?!
几秒钟后,您应该看到类似以下的消息:
Server running at http://localhost:1234
✨ Built in 3.15s.
服务器现在正在运行,如果打开浏览器并转到http:// localhost:1234 ,则可以看到该应用程序正在运行。 这将即时更新,因此您对代码所做的任何更改都会立即反映在页面上(或在短暂的暂停后重新生成代码)。 它还会热加载模块,因此它将自动安装所需的所有npm模块,就像使用“ node-sass”一样。 太棒了!
对网站的外观感到满意之后,就可以构建静态网站了。 首先,通过同时按住Ctrl和c来停止服务器运行。 然后在终端中运行以下命令:
./node_modules/.bin/parcel build src/index.html --out-dir docs --public-url ./
这将构建静态文件并将其放置在docs
文件夹中。
如果您在docs
文件夹中达到峰值,则应该找到一个名为index.html
的文件。 在浏览器中打开它,您应该看到站点正在运行,仅使用docs
文件夹中的静态文件。 Parcel将所有相关代码捆绑在一起,并使用Babel将我们的现代JavaScript转换为单个JavaScript文件,并使用node-sass将我们的SCSS文件预处理为单个CSS文件。 打开它们,您会发现代码也已最小化!
npm脚本
npm具有一个称为脚本的有用功能,该功能使您可以使用单个命令运行特定的代码段。 我们可以使用它来创建几个脚本,以加快我们对Parcel的使用。
将以下内容添加到package.json
文件的“脚本”部分:
"start": "parcel src/index.html --out-dir docs",
"build": "parcel build src/index.html --out-dir docs --public-url ./"
现在,我们只需运行以下命令即可启动服务器:
npm start
然后以下命令将运行构建过程:
npm run build
如果您从未使用过npm脚本,或者想复习一下,则可以阅读有关该主题的对初学者友好的教程 。
部署到GitHub Pages
GitHub是托管代码的好地方,它还有一个很棒的功能,称为GitHub Pages ,可让您在GitHub上托管静态站点。 首先,您需要确保您拥有GitHub帐户,并且在本地计算机上安装了git 。
为了确保我们不会提交不必要的文件,我们将gitignore
文件添加到hyperlist
目录中:
touch .gitignore
顾名思义,该文件告诉git应该忽略哪些文件(或模式)。 通常用于避免提交对其他协作者无用的文件(例如,IDE创建的临时文件等)。
我建议添加以下项目,以确保它们不会被git跟踪(请记住gitignore
是隐藏文件!):
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Dependency directory
node_modules
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
# Cache for Parcel
.cache
# Apple stuff
.DS_Store
现在我们准备在hyperlist
目录中初始化git:
git init
接下来,我们添加到目前为止已创建的所有文件:
git add .
然后,我们将这些文件提交给版本控制:
git commit -m 'Initial Commit'
现在,我们的重要文件已被git跟踪,我们需要在GitHub上创建一个远程存储库。 只需登录您的帐户,然后单击“ 新建存储库”按钮,然后按照说明进行操作即可。 如果您遇到困难,可以在这里查阅GitHub的文档: Create A Repo 。
完成此操作后,您需要在本地计算机上添加远程GitHub存储库的URL:
git remote add origin https://github.com/<username>/<repo-name>.git
确保将<username>
和<repo-name>
替换为正确的值。 如果要检查是否已正确完成所有操作,可以使用git remote -v
。
最后,我们需要将代码推送到GitHub:
git push origin master
这会将所有代码(包括docs
目录中的静态文件)推送到GitHub存储库。 现在可以将GitHub Pages配置为使用此目录中的文件。 为此,请登录GitHub上的存储库,然后转到存储库的“设置”部分,然后向下滚动至“ GitHub页面”部分。 然后在Source下,选择显示“ master branch / docs folder”的选项,如下面的屏幕截图所示:
这意味着您现在可以在以下地址访问该应用程序:https://username.github.io/repo-name。
例如,您可以在sitepoint-editors.github.io/hyperlist/上看到我们的。
工作流程
从现在开始,如果您对应用程序进行了任何更改,则可以遵循以下工作流程:
- 启动开发服务器:
npm start
- 进行任何更改
- 检查更改在开发服务器上是否有效
- 按住Ctrl + c关闭服务器
- 重建应用程序:
npm run build
- 分阶段提交更改:
git add .
- 提交对git的所有更改:
git commit -m 'latest update'
- 将更改推送到GitHub:
git push origin master
。
我们可以通过创建一个npm脚本来一次性完成最后三个步骤来加快此过程。 将以下内容添加到package.json
的“ scripts”条目中:
"deploy": "npm run build && git add . && git commit -a -m 'latest build' && git push origin master"
现在,如果要在进行任何更改后部署代码,您需要做的就是运行以下命令:
npm run deploy
够了,伙计们!
至此,本教程结束。 我使用了在本教程的第1部分中创建的应用程序,但是对于大多数JavaScript项目,其原理仍然相同。 希望我已经展示了使用Parcel构建静态JS网站并通过一个命令自动将其自动部署到GitHub Pages的过程是多么容易!
翻译自: https://www.sitepoint.com/parcel-hyperapp-github-pages/
添加parcel 到cdh