用Gatsby和Strapi创建一个静态博客

本文以简单通俗的方式讲解了结合Gatsby和Strapi创建一个静态博客的方法和具体步骤, 也额外插入了许多创建过程中遇到的各种问题和解决办法.

原文参阅: Building a static blog using Gatsby and Strapihttps://blog.strapi.io/buildi…. 本篇首发在SegmentFault上, 用Markdown语法, 所以美观性相比更强. 本篇主要是对原文精华内容进行翻译, 以及实操过程中遇到的问题解决和探索. 一些具体的操作步骤和细节, 我将忽略, 结合原文一起阅读效果更佳!

注: 本文操作环境是Linux VPS, CentOS 6 64bit

介绍

这是一个包含很多静态内容页面的站点, 从技术上来说就如同一系列HTML文件, 展示给访问者. 与动态网站不同的是, 他不需要后端开发或者数据库支撑. 发布静态站点之所以容易, 是因为文件只需要上传到服务器或者存储器. 没有额外的渲染页面的请求, 也没有数据库被黑的风险, 所以它既安全也快速.

为了快速建站, 其实很多开源的静态页面生成框架可用, 比如前阵子我搞的Jekyll, Hugo, 好似国人偏爱的Hexo等等, 他们的工作原理相似, 内容都是通过静态文件(比如Markdown)或者带有内容的API, 通过获取这些内容, 注入到开发者做好的模板, 最后生成一大堆HTML文件.

Progressive Web Apps (PWA)实际上是网页应用, 几乎基于Javascript, 并且可靠, 快速, 有吸引力的. 这几年比较火的Angular, Vue, React都是类似的前端框架.

静态站点遇见了PWA就产生了Gatsby

将这两点组合起来的最佳选择看起来就是Gatsby了, 但是同样需要一个内容接口, 这就是我将要展示的, 通过Strapi创建一个内容API提供给Gatsby, 然后打包发布出一个静态站点.


Gatsby是什么

这个并不是型男熟知的杰士派, 虽然我也用过这个发泥, 好像不是很好用. Gatsby是基于React的快速静态网站框架, 有了它, 你就可以感觉飘飘然的开发React网站了.

Strapi是什么

Strapi是一个基于高级的Nodejs API内容管理框架. 听起来有点绕口, 通俗来说就是让你能简单, 安全, 高效的开发出强大API的开源的内容管理框架. 它是免费的, 人们都爱免费的, 可以随意在你的服务器上使用, 也非常具有可个性化, 可扩展性的玩意.

我真想不到国内几乎没有人用Gatsby和Strapi, 百度上查不到任何资料…

创建API

见证奇迹的时刻即将到来, 我们快创建个Strapi API, 添加点内容吧!

创建Strapi项目

Requirements: please make sure Node 8 (or higher) and MongoDB are installed and running on your machine.

此时, 暗喜前阵子已经琢磨出来了并装好了Node 8, 不过装MongoDB就没有了. 因此这里就要插入一段关于MongoDB的内容了. 如果已经有了请自动跳过此内容.

MongoDB安装及相关问题

果断找到文档Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux, 这个redhat和centOS应该是通用的吧- -! 看到Configure the package management system (yum)., 发现原来还有这种操作, 创建repo文件, 来安装对应版本的软件. 闲话少说, 直接上代码:

# cd /etc/yum.repos.d/
# touch mongodb-org-3.6.repo
# vi mongodb-org-3.6.repo

将以下内容copy进去保存

[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc

再进行安装

# sudo yum install -y mongodb-org

如果有特殊需求, 请参阅上文提到的官方文档, 我这里装的是MongoDB Community Edition

按以上步骤很快就装好了. 接下来启动mongod(如果没有启动的话), 如下命令:

# service mongod start

完成后, 我们接着创建Strapi项目的主题, 推荐安装strapi@alpha版本:

# npm i strapi@alpha -g

完成后, 去到你要创建本文项目的目录, 比如我这里的路径是/home/web/, 我在这里创建一个gatsby-strapi-tutorial目录:

# mkdir gatsby-strapi-tutorial

在这里面搭一个API脚手架

# cd gatsby-strapi-tutorial
# strapi new api

进入项目目录, 并运行Node.js服务器

# cd api
# strapi start

遇到了一些小问题

这里突然时不时卡住了, 如果你很顺利, 那么可以跳过此内容, 频繁报错如下

[root@whidy api]# strapi start
DEBUG (24910 on whidy): Server wasn't able to start properly.
ERROR (24910 on whidy): (hook:mongoose) takes too long to load

大概是网络原因, 我联通网络出问题, 换了电信几番尝试就好了.

操作过程中频繁出现刚才的问题, 我觉得不是网络问题那么简单, 我打算从数据库方面着手完善一下试试, 当然后来证明, 一切问题都与MongoDB无关, 所以下面缩进内容可以选择性阅读大多数情况下我是不愿意理睬WARNING信息的, 只要不是ERROR就好, 但是这次我有点不爽, 后来折腾了半天发现有的很难处理, 好吧我错了, 我想我还是不死磕了吧😱.

  • soft rlimits too low
    WARNING: soft rlimits too low. rlimits set to 1024 processes, 64000 files. Number of processes should be at least 32000 : 0.5 times number of files.

    参阅:

  • versions of RHEL older than RHEL6
    WARNING: You are running in OpenVZ which can cause issues on versions of RHEL older than RHEL6.

    服务器硬件限制? 可以安全忽略.

    参阅: WARNING: You are running in OpenVZ which can cause issues on versions of RHEL older than RHEL6.

  • Access Control
    以为要搞账户什么的, 然后运行mongo命令, 创建了一个admin账户:

    # mango
    > use admin
    > db.createUser(
        {
          user: "username",
          pwd: "userpassword",
          roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
        }
      )
    # mongo --port 27017 -u "username" -p "userpassword" --authenticationDatabase "admin"

    其实我自己当时也不知道是搞啥, 其实完全没关系的操作. 很多人甚至官方文档Start MongoDB without access control.也提到:

    mongod --port 27017 --dbpath /data/db1

    可是我一直报错, 要么说不存在, 搞半天才明白, 要手动创建, 创建好了, 又说服务被占用, service mongod stop停了服务, 连上去了, show dbs发现跟之前的又不一样, 没有找到我之前看到的strapi库, 才恍然大悟, 原来其实我创建了一个跟之前无关的库…

    事实上, 启动mongod服务的时候, 它连接了一个默认配置库, 这个库的路径时早就创建好的, 通过查看/etc/mongod.conf这个文件就知道了. 因此删了那个没用的db目录. 接着操作.

    后来第二天早上, 再次执行strapi start很顺利. 我也没办法再研究昨天究竟是为什么总是连不上了. 反正就是渣渣网络经常会带来各种坑!😡, 这段没什么作用的内容就过去了.

回到刚才strapi start, 成功之后, 我们如果是本地操作的, 带有界面的操作系统的话就可以直接访问http://localhost:1337/admin了, 如果也是远程操作, 就改成IP就好了.

接下来的操作是创建用户, 原文已经图文并茂, 傻子都能看懂的步骤了, 由于篇幅过大, 我就简单翻译一下, 不详细复述了嘿嘿~

按照原文操作:

  1. 创建管理员账号(Create your first User)
  2. 创建内容类型(Create a Content Type)
    名为article的内容类型有三个字段: title(字符串), content(文本), author(关系, 多文章对应一个用户).
  3. 添加几项内容到数据库
    1. 访问文章列表页
    2. 点击Add New Article
    3. 插入值, 连接对应的作者并保存
    4. 重复以上操作, 创建额外两篇文章
  4. 允许API权限, 依原文对应勾选保存

完成后, 就可以访问http://localhost:1337/article了.

创建静态站

到目前, 你的API搞定了, 我们要搞静态网站啦

安装Gatsby

首先, 全局安装Gatsby CLI:

# npm install --global gatsby-cli

生成Gatsby项目

回到之前提到的gatsby-strapi-tutorial目录, 创建一个新博客:

# gatsby new blog

事情总是不是那么顺利.

报错, 需要git. 然而我的这台崭新的服务器还没装, 那就装一个吧.

如果你的git已经部署OK, 并且上面这个操作没有问题, 以下内容可忽略:

参考Download for Linux and Unix执行:

# yum install git

再次执行后依旧报错(当前git版本1.7.1)

error Command failed: git clone git://github.com/gatsbyjs/gatsby-starter-default.git blog --single-branch

推测是版本问题. 只好手动安装了. 于是又找到这个安装 Git

# yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
# wget https://www.kernel.org/pub/software/scm/git/git-2.16.1.tar.gz
# tar -zxf git-2.16.1.tar.gz
# cd git-2.16.1
# make prefix=/usr/local all
# sudo make prefix=/usr/local install

漫长的make prefix=/usr/local all之后, 提示:

    SUBDIR perl
/usr/bin/perl Makefile.PL PREFIX=\'/usr/local\' INSTALL_BASE=\'\' --localedir=\'/usr/local/share/locale\'
Can\'t locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 3.
BEGIN failed--compilation aborted at Makefile.PL line 3.
make[1]: *** [perl.mak] Error 2
make: *** [perl/perl.mak] Error 2

蛋疼, 等了半天, 又要解决这个问题, 好在看起来比较容易处理, 参考git fails to build in Fedora 14, 然后继续执行最后两条make命令, 虽然最后出来很多看起来很奇怪的内容, 不过似乎是成功了. 执行:

# git --version
git version 2.16.1

接下来我们再一次执行gatsby new blog, 我擦还提示刚才的...single-branch的error, 这就坑爹了- -. 经过简短的排查. 原来似乎他还是跑的旧版git, 需要删掉之前yum自动安装的git 1.7.1, 我单纯的以为直接自动升级了. 于是:

# yum remove git

按照提示删除成功后, 再次检测git还是ok的, 这次我第三次执行gatsby new blog, 终于成功了!

我这小白也不知道linux软件管理是咋整的. 反正能继续执行卡了我半天的gatsby就好了吧…每次创建速度很慢, 执行gatsby new blog完成的时候提示added 1398 packages in 137.652s, 大概就是2分钟多, 可能是安装依赖包费时吧

启动开发模式

创建成功后, 接着操作, 进入博客目录

# cd blog

启动服务器

# gatsby develop

理论上你就可以通过http://localhost:8000访问到默认的效果博客站点了.

然而又一次出现小插曲, 如果你是和我一样远程访问, 也许以下内容对你有用

每次执行gatsby develop的时间甚至更长, 完成时提示如下:

info bootstrap finished - 334.876 s

DONE  Compiled successfully in 90373ms 21:15:06


You can now view gatsby-starter-default in the browser.

http://localhost:8000/

View GraphiQL, an in-browser IDE, to explore your site's data and schema

http://localhost:8000/___graphql

Note that the development build is not optimized.
To create a production build, use gatsby build

大概用了6分钟左右, 糟糕的是并不能通过远程IP来访问! 查看了目录下的配置文件和官方文档, 也没查到. 绝望之时, 突然在大量资料中看到webpack也有这样的问题, 想起来之前webpack的server默认配置也是无法通过ip访问, 但是webpack的devServer配置host: "0.0.0.0"即可, 试了下:

# gatsby develop --host 0.0.0.0

又经过4分钟左右漫长等待, 这次成功了! 不过我尝试搜索Gatsby究竟用的什么服务器启动, 为何不能像webpack那样加一段配置呢, 却没有找到. 后来凑巧找到了一篇webpack下的issue, Server can’t be accessed via IP, 有人提到过这条命令.

因此, 从小插曲中来看, 远程访问控制的开发者, 需要加个参数, 具体命令:

# gatsby develop --host 0.0.0.0

这样, 至此开发模式服务器搞定.

安装Strapi插件(Install the Strapi source plugin)

Gatsby understands this pretty well. So its creators decided to build a specific and independent layer: the data layer. This entire system is strongly powered by GraphQL.

前面有一些插件介绍不多说了, 执行安装:

# npm install --save gatsby-source-strapi

完成后, 需要做些配置, 修改gatsby-config.js文件, 替换成以下内容:

module.exports = {
  siteMetadata: {
    title: `Gatsby Default Starter`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-source-strapi`,
      options: {
        apiURL: `http://localhost:1337`,
        contentTypes: [ // List of the Content Types you want to be able to request from Gatsby.
          `article`,
          `user`
        ]
      },
    },
  ],
}

保存后, 重启Gatsby服务器

文章列表

为了在首页显示文章列表, 我们需要修改首页代码如下:

路径: src/pages/index.js

import React from 'react'
import Link from 'gatsby-link'
const IndexPage = ({ data }) => (
  <div>
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
    <ul>
      {data.allStrapiArticle.edges.map(document => (
        <li key={document.node.id}>
          <h2>
            <Link to={`/${document.node.id}`}>{document.node.title}</Link>
          </h2>
          <p>{document.node.content}</p>
        </li>
      ))}
    </ul>
    <Link to="/page-2/">Go to page 2</Link>
  </div>
)
export default IndexPage
export const pageQuery = graphql`
  query IndexQuery {
    allStrapiArticle {
      edges {
        node {
          id
          title
          content
        }
      }
    }
  }
`

这里就应用到了GraphQL啦, 好激动呢. 我们导出pageQuery, 一个GraphQL查询会请求文章列表, 我们只需要将需要查询的字段添加进去就好了~

然后我们传递{ data }这个结构对象作为IndexPage参数, 遍历它的allStrapiArticles对象, 来展示数据.

GraphQL查询可以快速生成, 你可以尝试在http://localhost:8000/___graphql修改, 并测试.

文章页

首页有了列表之后, 我们还要访问文章页面呢, 接下来写一个模板:

路径: src/templates/article.js

import React from 'react'
import Link from 'gatsby-link'
const ArticleTemplate = ({ data }) => (
  <div>
    <h1>{data.strapiArticle.title}</h1>
    <p>by <Link to={`/authors/${data.strapiArticle.author.id}`}>{data.strapiArticle.author.username}</Link></p>
    <p>{data.strapiArticle.content}</p>
  </div>
)
export default ArticleTemplate
export const query = graphql`
  query ArticleTemplate($id: String!) {
    strapiArticle(id: {eq: $id}) {
      title
      content
      author {
        id
        username
      }
    }
  }
`

你需要手动创建这个目录和文件, 当然Gatsby并不知道模板何时展示. 每篇文章都需要一个特别的URL, 感谢Gatsby提供的createPage函数.

首先, 我们写个makeRequest函数来处理GraphQL请求. 然后通过createPage函数使我们在获取的文章列表后为它们创建一个页面, 路径为文章id的URL, 回到blog目录, 修改gatsby-node.js文件

const path = require(`path`);
const makeRequest = (graphql, request) => new Promise((resolve, reject) => {
  // Query for nodes to use in creating pages.
  resolve(
    graphql(request).then(result => {
      if (result.errors) {
        reject(result.errors)
      }
      return result;
    })
  )
});
// Implement the Gatsby API “createPages”. This is called once the
// data layer is bootstrapped to let plugins create pages from data.
exports.createPages = ({ boundActionCreators, graphql }) => {
  const { createPage } = boundActionCreators;
  const getArticles = makeRequest(graphql, `
    {
      allStrapiArticle {
        edges {
          node {
            id
          }
        }
      }
    }
    `).then(result => {
    // Create pages for each article.
    result.data.allStrapiArticle.edges.forEach(({ node }) => {
      createPage({
        path: `/${node.id}`,
        component: path.resolve(`src/templates/article.js`),
        context: {
          id: node.id,
        },
      })
    })
  });
  // Query for articles nodes to use in creating pages.
  return getArticles;
};

再次重启Gatsby服务器.

现在你就能通过点击首页的文章进入到文章内容页面了.

作者页

虽然这个似乎并不重要, 不过还是加上学习一下吧😁

添加作者页和创建文章页很相似, 我们还是先创建个模板:

路径: src/templates/user.js

import React from 'react'
import Link from 'gatsby-link'
const UserTemplate = ({ data }) => (
  <div>
    <h1>{data.strapiUser.username}</h1>
    <ul>
      {data.strapiUser.articles.map(article => (
        <li key={article.id}>
          <h2>
            <Link to={`/${article.id}`}>{article.title}</Link>
          </h2>
          <p>{article.content}</p>
        </li>
      ))}
    </ul>
  </div>
)
export default UserTemplate
export const query = graphql`
  query UserTemplate($id: String!) {
    strapiUser(id: { eq: $id }) {
      id
      username
      articles {
        id
        title
        content
      }
    }
  }
`

然后再次修改gatsby-node.js来创建作者URLs:

const path = require(`path`);
const makeRequest = (graphql, request) => new Promise((resolve, reject) => {
  // Query for article nodes to use in creating pages.
  resolve(
    graphql(request).then(result => {
      if (result.errors) {
        reject(result.errors)
      }
      return result;
    })
  )
});

// Implement the Gatsby API “createPages”. This is called once the
// data layer is bootstrapped to let plugins create pages from data.
exports.createPages = ({ boundActionCreators, graphql }) => {
  const { createPage } = boundActionCreators;
  const getArticles = makeRequest(graphql, `
    {
      allStrapiArticle {
        edges {
          node {
            id
          }
        }
      }
    }
    `).then(result => {
    // Create pages for each article.
    result.data.allStrapiArticle.edges.forEach(({ node }) => {
      createPage({
        path: `/${node.id}`,
        component: path.resolve(`src/templates/article.js`),
        context: {
          id: node.id,
        },
      })
    })
  });
  const getAuthors = makeRequest(graphql, `
    {
      allStrapiUser {
        edges {
          node {
            id
          }
        }
      }
    }
    `).then(result => {
    // Create pages for each user.
    result.data.allStrapiUser.edges.forEach(({ node }) => {
      createPage({
        path: `/authors/${node.id}`,
        component: path.resolve(`src/templates/user.js`),
        context: {
          id: node.id,
        },
      })
    })
  });
  // Queries for articles and authors nodes to use in creating pages.
  return Promise.all([
    getArticles,
    getAuthors,
  ])
};

重启服务器, 刷新页面, Wow! 大功告成! 时不时很酷!!!

原文总结

恭喜, 你成功的创建了一个超快的很好维护的博客! 然后各种夸奖Blabla

接下来做什么呢? 你可以去更多的挖掘Gatsby和Strapi的各种优点, 你可以试着增加这些功能:

  • 作者列表
  • 文章分类
  • 用Strapi API创建评论系统, 或者直接用Disqus
  • 当然你也可以试着搞其他站点, 例如电商站, 企业站等等

当然为了进一步方便开发, 你可能需要一个方便的发布在网上的存储载体, Blablabla…

本教程GitHub源码地址, 你可以clone下来, 运行npm run setup, blablabla… 我是个爱研究的人, 我要一步步操作, 才不要clone.

个人总结

这次通过Gatsby和Strapi搭建一个简单的博客站点, 还是挺不容易的, 总共花了将近两天的时间. 不过个人感觉还是值得的! 其中有很多地方是可以更加深入的学习和了解的, 这也算初步接触了react, mongodb, graphQL等相关知识实操, 同时也可以在后期完善更多的功能, 了解并学习一些ES6, 模板的写法技巧等等. 也希望通过此次研究以后能更进一步熟悉其他框架, 数据库, 后端等思想~

相关参阅汇总

最后打个小广告, 我有个GitHub项目, 用于记录我每天学习或者瞎折腾的技术, 范围不限, 有兴趣可以star我的whidy daily

Visual Studio Code几款FTP插件使用总结

投入Visual Studio Code后,很久没有使用过sublime text了,也很久没有用过基于编辑器的ftp工具了,这次专门探索了一下Visual Studio Code几款FTP插件,并作了简单的总结,ftp-sync是最棒的!

平时要维护类似wordpress这样的网站,然后虚拟主机又不支持远程仓的版本管理。总而言之,只能通过下载到本地修改后再通过FTP上传的情况,每次修改后都要开启FTP进行代码提交,相当繁琐。因此就诞生了一些编辑器的FTP插件,其实以前用sublime text的时候还有款插件叫SFTP不错(如果配置好了连接不上可以参考SFTP连接超时),可惜VSCODE上面没有,截至目前(2018年1月17日)可以用的FTP插件如下图:

vscode的ftp插件
vscode的ftp插件

为了找出最合适的插件,我全部都一个个试过了(关于如何使用参考插件说明,十分简单就不多说了)。然后有以下感想:

  1. ftp-sync是测试中的唯一一个感觉还可以的,但是菜单为啥不全,感觉是一个BUG吧.希望后期能够优化.

    ftp-sync菜单
    ftp-sync菜单
  2. SFTP/FTP sync总是回莫名其妙的卡住(左下角提示transfer就不动了),而且相同文件好像也会再次覆盖,不会跳过.文件比较多的时候出问题,不建议使用.
  3. ftp-kr跟Simple FTP/SFTP一样没啥暖用,还不如就用ftp软件操作
  4. Simple FTP/SFTP没啥暖用,还不如就用ftp软件操作

感觉很惨,没有一个真正好用的,而且连ftp传输状态信息也没有.有时候比较惨的误操作了需要中断传输,貌似只能强制关闭编辑器…

最后感觉,还是用sublime text 的SFTP来维护会比较好一点.如果不怎么用sublime text的话,个人建议使用ftp-sync在VSCode上表现还是不错的,有潜力,期待作者进一步优化~

Linux下无法正常安装(升级)和删除Nodejs的解决方法

Linux(CentOS6)下安装Nodejs,删除Nodejs,升级Nodejs遇到的一些问题,以及相关解决方案的介绍

接着上次说,自从买了VPS后就没闲着,总想要充分利用起来倒腾点东西。于是决定安装nodejs搭建web服务器等,如今nodejs稳定版本已经更新到8.x了,因此我就试着装一下8.x吧,没想到又遇到了坑,一搞搞了好几天。

我的操作系统是CentOS 6 64 Bit的,我查阅了Nodejs官方升级文档(包含各种可支持的系统),针对我的系统需要分别执行以下几条命令:

curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
sudo yum -y install nodejs

当然你也许需要通过以下命令额外安装构建工具:

sudo yum install gcc-c++ make
# or: sudo yum groupinstall 'Development Tools'

如果其他系统则可以参考文档中其他内容。

在这里我就遇到坑了(可能存在该情况较少,所以稍后具体解决放在文章最后来说)。上面第一条应该是静默指定使用8.x的资源,便于安装时采用这个而不是yum自己原来的远程仓,不知道这个解释对不对。

我反复试过了,命令明明提示请执行 sudo yum -y install nodejs 来安装nodejs8.x,却一直安装的是6.x,难道是依赖问题?找不出原因的我,没有办法只能找其他安装途径,于是发现了第二种安装办法,手动获取最新的安装包,并进行解压缩安装,可能依赖Python2.7以上版本,我一步步来说。

如果是仅手动安装Nodejs8.x,执行以下命令:

yum install gcc-c++ openssl-devel
cd /usr/local/src
wget http://nodejs.org/dist/v8.9.4/node-v8.9.4.tar.gz
tar zxvf node-v8.9.4.tar.gz
(cd into extracted folder: ex "cd node-v8.9.4.tar.gz")
./configure
make
make install

顺利的话应该不会有什么问题,大概会过一段时间,稍微有点长,就提示安装好了,可以执行

node -v

来查看是否是8.x,如果好了,基本上关于安装部分就大功告成了。如果没好,太惨了,跟Python有关系的话,请查看Linux下Python安装升级心得

接着我们来看看删除,因为你已经安装了一个低版本,需要升级,那就是要先删除旧版本了,nodejs应该是向下兼容的,所以我就没有去研究可能闲着蛋疼才会去研究如果保存多个版本nodejs,当然在新版中可能会存在部分旧的功能废除而造成异常,虽然一般来说升级利大于弊,不过还是要考虑老项目环境是否要升级!如果你是闲着蛋疼的人,必有理由说服我,请在下方留言。差点跑题,删除命令简直是太简单了。

sudo yum remove nodejs

然后按提示输入y,回车后很快就删了。一切删除操作都是令人兴奋的。。。

其实,我在安装过程中远没有那么轻松,否则也不会折腾几天了,一个是版本错误,一个是Python升级。版本问题,后来差了很多资料才发现,原来是yum缓存问题导致。如果遇到和我类似的问题,请尝试以下命令:

rm -f /etc/yum.repos.d/nodesource-el.repo
yum clean all
yum -y remove nodejs
yum -y install nodejs

汇总下本文参阅的相关文章:

  1. Nodejs官方文档,通过包管理安装Nodejs
  2. Centos下手动安装Nodejs的方法
  3. 无法在Yum仓下安装正确的Nodejs版本(和刚才示例的代码类似,都是清除缓存,不过对我无效)
  4. CentOS下使用nodejs7.x的包进行安装却安装成了6.9.5(针对我的有效方案)
  5. 如何通过Linux命令删除Nodejs

所以我呢,其实就是应该遇到版本不对的情况就尝试清除缓存,再用官方命令进行安装就好了~

我想既然是Yum仓库缓存的问题,除了Nodejs,别的包也许也会有类似情况吧,如果也发现了选择了需要的版本后依然装的是旧版的,又和依赖没什么关系,就试试清除缓存吧 🙂

Chrome启动关联程序的协议链接误操作被禁用后如何修改设置重新开启

由于误操作,造成Chrome启动关联程序的协议链接被禁用,那么怎么重新修改设置,启动相关的程序呢,这里将为大家解答!

该文章适用于Windows 7 x64下Chrome版本 62.0.3202.94(正式版本) (64 位)的设置,其他设备不明。也许WIN10也可以,但是可能会由于Chrome版本区别而不可用。

今天回到宿舍,要用百度云盘下载点东西,结果,手误,勾选记住后,点了不要打开,为什么要高亮不要打开,泪奔。。。界面是这样的:

百度云的链接协议设置protocol settings

继续阅读“Chrome启动关联程序的协议链接误操作被禁用后如何修改设置重新开启”

表单中readonly的input等标签,禁止光标进入(focus)的几种方式

在做移动端页面,表单内的部分元素如果设置了readonly=”readonly”,CHROME模拟移动端是看不出问题的。而手机上虽然表单元素不能编辑内容,但是会出现闪动的光标以及页面底部有一条系统自带的控制bar。这样的体验很差,于是我总结了几个方案。

在做移动端页面,需要在订单页面中显示表单数据,由于UI统一,所以就依旧采用form的结构来写结构,只读数据的标签自然要加readonly=”readonly”,以为这样就行了,CHROME模拟移动端是看不出问题的。手机上一看,虽然表单元素不能编辑内容,但是会出现闪动的光标以及页面底部有一条系统自带的控制bar。

表单readonly元素依然有光标
表单readonly元素依然有光标,底部还有BAR,感觉不好

这种情况对我来说并不好。于是网上找了一些解决方案,现在总结一下:

方案一(JS):

<input type="text" value="test" onfocus="this.blur()" readonly="readonly">

这个很好理解就是进入的时候自动跳出。但是缺点是一方面js处理没有css好,二是如果需要在该元素上绑定其他事件,其他人开发不留意可能会造成事件覆盖。

方案二(CSS):

[readonly="readonly"] {
  user-select: none;
}

这是个新的实验性属性,具体说明及兼容性可参考user-select MDN
用起来感觉很好,但是同样有两个问题:一,非标准属性(请尽量不要在生产环境中使用它!);二,如果用户想要复制该表单内容就不行了,这个问题个人感觉很严重!

方案三(CSS):

[readonly="readonly"] {
  pointer-events: none;
}

这个是我感觉比较适合我的,因此最后我采纳了该方案,当然也是有弊端的,绑定在只读表单元素的所有事件将无法生效。除此之外都表现完美,就我目前需求来看,也不需要什么事件。因此采用了~

当然,如果你也遇到相似的问题,可以根据情况选择对应的方案,当然,如果你也有更好的方法也欢迎留言~

PostCSS学习指南(二)

关于我最近学习PostCSS的一些相关心得和总结,主要介绍项目中可能用到的一些插件比如autoprefixer,postcss-partial-import,postcss-advanced-variables,cssnano,postcss-px2rem,precss等等

(推荐访问github上面的Markdown排版的介绍PostCSS学习指南(二))

继上一次PostCSS学习指南(一)后,渐渐开始在项目中应用。

这次决定主要讲解一些个人认为非常有帮助的PostCSS插件。

本期主要介绍以下几个插件和几个坑

  1. autoprefixer
  2. postcss-partial-import
  3. postcss-advanced-variables
  4. cssnano
  5. postcss-px2rem
  6. precss
  7. postcss-nestingpostcss-nested
  8. 坑( ఠൠఠ )ノ

autoprefixer

这个就不用多说了,必装插件之一。方便的写规范的css,它会为你提供非常完整的hack兼容方案的。当然这里需要了解一下的是,它的大部分兼容数据来源Can I Use,另外一个稍微需要了解的插件配置参数就是browsers,比如这样写:

module.exports = {
  plugins: [
    require('autoprefixer')({ browsers: 'last 2 versions' })
  ]
}

关于这个参数的详细介绍可以看看Browserslist Queries,文中说了,强烈建议将查询写入package.json(后面会告诉你为何要写在这里),而非配置postcss.config.js中autoprefixer的browsers参数。所以此处建议写法如下: 继续阅读“PostCSS学习指南(二)”

PostCSS学习指南(一)

关于我最近学习PostCSS的一些相关心得和总结

(推荐访问github上面的Markdown排版的介绍PostCSS学习指南(一))

PostCSS介绍

PostCSS是一个利用JS插件来对CSS进行转换的工具,这些插件非常强大,强大到无所不能。其中,Autoprefixer就是众多PostCSS插件中最流行的一个。

截至目前(2017年7月)PostCSS已经有超过200个插件,你可以插件列表查找有没有你所需要的插件。如果你想自己写个插件,据说这是一个不错的主意,而且非常简单,你可以试着搞点事

看到这里,你可能没有发现它的强大之处,甚至我自己都没有被我翻译的这段官方文字所打动。~~因为没(wǒ)有(yě)对(bù)比(tài)就(huì)没(yòng)有(zhè)伤(wán)害(yì)。~~好了,是时候启动装逼模式了。

维基百科,阿里巴巴,谷歌,Wordpress,Twitter等网站均有使用,大佬们都在用你有什么理由不跟上步伐。

再来看看这张PostCSS下载数量的npm-stat统计表(数据证明一切):

PostCSS下载数量

学习PostCSS之前需要了解一些事情:

  1. PostCSS插件的处理方式类似那些CSS预处理器,而非预处理器和后处理器(PostCSS is Not a *Pre-*processor and Not a *Post-*processor either
  2. PostCSS is Not “Future Syntax”(不是新式语法?不知道怎么翻译)
  3. PostCSS本身并非整理或优化CSS的工具
  4. PostCSS可以完成很多意想不到的事情,例如用postcss-rtl恶搞一下:yum:

那么它还有一些特性,例如创建了一个插件功能极强的生态系统,具有模块化需要什么用什么(precss就是一个集成了类似SASS的包),相比其他的CSS预处理器它的优势主要体现在以下几个方面:

  1. 拥有极高的处理性能(3倍以上的处理速度
  2. 你既可以写正常的CSS,也可以结合LESS或者SASS一起编写
  3. 对Source Map支持更好
  4. 他的插件真的太多太强大太便利了

其他对比SASS和LESS的区别在于他们内置了大量的方法,而也许你只需要用到几个变量而已,大材小用。而PostCSS则可制定个人需求的一套解决方案(仅安装需要的插件)。这也就是他高性能的主要原因。几乎SASS和LESS有的功能全都有!

总之好处太多了。这里就不一一列举了。迫不及待的你已经等不及安装使用了吧。

继续阅读“PostCSS学习指南(一)”

安装node-sass的时候报错 Cannot download “https://github.com/sass/node-sass/releases/download/v4.5.3/win32-x64-48_binding.node”:

搭建项目环境需要安装node-sass,经常会出现错误,提示https://github.com/sass/node-sass/releases/download/v4.5.3/win32-x64-48_binding.node无法下载,原因就是国外的东西很慢,解决办法也很简单…

最近重装了系统在配置项目环境时需要用到node-sass,经常出现安装失败的情况.

以前也是又是装python又是配环境,也不知道到底是怎么瞎折腾出来的的.好不容易弄好了就没管了.

这次搞虚拟机测试了一下,有个很好的解决方案.是在github上node-sass的issues看到的,屡试不爽,当然如果你也是我这种情况可以试试.我想大部分情况都能解决吧.

先看看我的出错信息

安装node-sass错误信息
安装node-sass错误信息

如果你也是这样的不妨将提示中的这个https://github.com/sass/node-sass/releases/download/v4.5.3/win32-x64-48_binding.node下载下来,存放在C:\Users\Whidy(你的用户)\AppData\Roaming\npm-cache\node-sass\4.5.3目录内,再尝试重新执行npm install node-sass我想应该就可以成功了吧.

当然版本不同的话会略有差异.请自行对应替换,如果你发现还是下载的很慢,我这里分享一下我上传到百度云的这个4.5.3版本的win32-x64-48_binding.node,然后拷贝到刚才说的目录就好了.

参考: Install node-sass 4.5.0 failed on window 7, “Binary has a problem: Error: %1 is not a valid Win32 application.”.

node搭本地服务器局域网内其他设备无法访问的问题

最近公司网络调整,本来记得之前手机访问电脑的服务器好端端的,突然就不好使了…

找了公司网络维护来看看,一时也没看出来.不过测了一下其他人的电脑搭建的服务器是可以访问的.于是推测是本机问题…可是一直没有对本机的网络有修改调整,怎么就突然不行了.只好自己动手查问题.

初步推测防火墙设置.简单暴力的办法关闭防火墙.果然通了…但是个人不喜欢关防火墙,感觉不安全了哈哈哈,其实是觉得小题大做,应该从根本解决问题.

回忆之前本地maven服务器,wamp搭建的服务器都好好的.大概是幻觉,也就是node搭建的服务器我或许没测过.好吧废话少说.不能访问的地址是192.168.1.107:9000,我就查一下什么程序用9000窗口,如下:

占用9000端口的是node.exe
占用9000端口的是node.exe

防火墙状态写了不允许,我猜大概就是这里了.

回到防火墙设置,在允许的应用中,我发现,专用网络的勾没有勾上(如下图),估计问题就在这里,于是勾上,确认后,BINGO…

防火墙node设置规则
防火墙node设置规则

拿出手机刷新一下,好了~

问题就解决了,问题其实解决起来很简单,不过对于网络这块不是很懂的,也遇到类似问题的可以通过类似的办法处理试试.

(话说出现这样的问题会不会是因为我第一次使用node启动服务器时候,弹出来的防火墙提示我误点了不允许导致的- -)

Visual Studio Code 设置同步到github的插件介绍及使用方法(Settings Sync)

今天要说的就是这个插件Settings Sync,一个可以在github上面通过gist仓来同步用户的vscode的配置包括插件,settings等信息的好插件

最近基本上习惯了用VSCODE进行开发了.最主要的感觉就是查找JS里面函数定义和引用很方便.还有可能是装逼心理… 🙄

一开始不知道怎么备份VSCODE的配置,傻乎乎的把要用的插件抄下来,还有用户settings拷贝出来.每次换了电脑或者重装系统什么的都要重新备份.虽然来回调整的概率很低,但是突然哪天需要同步设置什么的就很麻烦了~至少我是在初期经常鼓捣这个编辑器,而且办公在家和公司是不同的设备~所以觉得还是很有必要的~

于是我今天要说的就是这个插件Settings Sync

官方都是英文的,不过还算简单,我把步骤简化一下.

1.安装插件并重启VSCODE就不用说了

安装Settings Sync
安装VSCODE Settings Sync后重新加载

2.重启后按快捷键 alt+shift+u (这里假设你第一次用)

它会弹出一个窗口对应的是github上面的创建个人gist的页面,如果未登录请先登录github.

github创建gist来存储设置
github创建gist来存储设置

保存后会生成一个key

请牢记token id,后面将会用到
请牢记token id,后面将会用到

3.切回到vscode,他会有个输入区,就是存放刚才生成的key

输入刚才生成的key
输入刚才生成的key

然后理论上他就开始对你本机的配置进行一个扫描上传了.至此上传工作完成.

接下来我们到另一台电脑上了下载配置.同样的先安装Settings Sync插件,并重新加载.

然后按快捷键alt+shift+d,就应该会弹出一个输入框,请在这里输入之前保存下来的key(GIST ID),回车后将会自动下载之前上传的配置.

那么下载完成后,你这台电脑修改了相关配置再次上传就好了.是不是感觉方便多了~

其他的说明,如果在输入gist id写错了,读取不到的情况下,大概需要重置设置,按F1,输入sync,这里有重置选项.试试看~

重置sync的gist配置信息等
重置sync的gist配置信息等

还有些其他的功能例如自动上传下载等等,不是很常用,大家可以自行看看官方文档,基本的使用方法就是这样了,我写的如果有问题或者哪里不明白的可以留言- -.

下面是官方说明

http://shanalikhan.github.io/2015/12/15/Visual-Studio-Code-Sync-Settings.html

插件地址

https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync


2018年1月15日补充
有朋友留言说Settings Sync不能同步插件,我刚测试过是可以同步插件的哦~按Alt+Shift+D后左下角可以看到同步的进度,例如下图:

Settings Sync插件同步
Settings Sync插件同步