群组信息 私有

administrators

 

成员列表

  • RE: dotenv + nextjs

    其實在next.config.js裡加env,這個值會在build的時候被用上。

    const withPlugins = require("next-compose-plugins");
    const css = require("@zeit/next-css");
    
    // require("dotenv").config();
    
    const nextConfig = {
      target: "serverless",
      webpack(config) {
        config.module.rules.push({
          test: /\.(png|svg|eot|otf|ttf|woff|woff2)$/,
          use: {
            loader: "url-loader",
            options: {
              limit: 8192,
              publicPath: "/_next/static/",
              outputPath: "static/",
              name: "[name].[ext]"
            }
          }
        });
        return config;
      },
      env: {
        API_HOST: "http://www.localhost:3030"
      }
      // publicRuntimeConfig: {
      //   // Will be available on both server and client
      //   API_HOST: process.env.API_HOST
      // }
    };
    
    module.exports = withPlugins([[css]], nextConfig);
    

    這樣更好。
    注意使用"now"來部署是serverless,所以用不了publicRuntimeConfig。

    发布在 React
  • dotenv + nextjs

    新版NextJS(我用的是V9)是支持dotenv的。
    只需要:

    npm install dotenv
    

    然後在next.config.js裡加入一行:

    require("dotenv").config();
    

    無需很多過時的網絡教程說的要通過webpack把env導入config裡。
    但是要注意:

    • PORT = 5000 不能用 - 好像next.config.js是在APP運行後才加載的,那是默認3000已經定了
    • dotenv是服務器端的事,因為它要從文件系統裡讀取.env 所以你可能需要publicRuntimeConfig.
    • publicRuntimeConfig 不能和 target:serverless合用。
      我現在的next.config.js如下:
    const withPlugins = require("next-compose-plugins");
    const css = require("@zeit/next-css");
    
    require("dotenv").config();
    
    const nextConfig = {
      // target: "serverless",
      webpack(config) {
        config.module.rules.push({
          test: /\.(png|svg|eot|otf|ttf|woff|woff2)$/,
          use: {
            loader: "url-loader",
            options: {
              limit: 8192,
              publicPath: "/_next/static/",
              outputPath: "static/",
              name: "[name].[ext]"
            }
          }
        });
        return config;
      },
      publicRuntimeConfig: {
        // Will be available on both server and client
        API_HOST: process.env.API_HOST
      }
    };
    
    module.exports = withPlugins([[css]], nextConfig);
    

    在page/*.js下讀取publicRuntimeConfg 是這樣的: (有點麻煩)

    import getConfig from "next/config";
    const { publicRuntimeConfig } = getConfig();
    const authenticate = e => {
        e.preventDefault();
        if (username != "" && password != "") {
          axios
            .post(publicRuntimeConfig.API_HOST + "/authentication", {
              strategy: "local",
              email: username,
              password: password
            })
            .then(function(response) {
              console.log(response);
              signIn(username);
            })
            .catch(function(error) {
              console.log(error);
              setMessage("Invalid Login");
            });
        } else {
          setMessage("Please enter your username and password");
        }
      };
    
    发布在 React
  • NextJS + React + Semantic-UI

    項目使用Semantic-UI,其實可以直接用semantic-ui-css  但是它不支持自定義build,也就是所以css都是定義好了,你只能直接用,或者用override 的方法。
    另外一種方法是用‘Fomantic-UI ', 不爽的是這麼一來我的package.json又開始臃腫了。

      "dependencies": {
        "@zeit/next-css": "^1.0.1",
        "next-compose-plugins": "^2.2.0",
        "semantic-ui-react": "^0.88.1",
        "styled-components": "^4.3.2"
      },
      "devDependencies": {
        "file-loader": "^4.1.0",
        "fomantic-ui": "^2.7.8",
        "url-loader": "^2.1.0"
      }
    

    以上除了semantic-ui-react,其他都是為了可以用自定義主題而增加的。
    另外,還有

    • pages/_app.js
    • pages/_document.js
    • next.config.js
    • semantic.json

    另外在package.json裡加上一些scripts:

        "now-build": "npm run semantic:build && next build",
        "semantic:build": "cd .semantic && gulp build-css build-assets",
        "semantic:watch": "cd .semantic && npm run semantic:build && gulp watch",
    

    請到這裡下載這些文件:https://github.com/skydiver/nextjs-semantic
    之後,run

    npm install
    npm run semantic:build
    npm run dev
    

    這樣就差不多了。

    发布在 React
  • 最新REACT項目設置 - nextjs, vscode, eslint, prettier

    這裡想介紹一下我的React新項目設置

    輕裝上陣

    React很酷,但是要維護一堆的packages不是一件容易的事。我看好多開發人員是乾脆不理會outdated的packages,能用就行。
    如果你有更新慾望症,那麼或許可以試試NextJS,建立一個簡單的App,只需要這些packages:

      "dependencies": {
        "isomorphic-unfetch": "^3.0.0",
        "next": "^9.0.5",
        "react": "^16.9.0",
        "react-dom": "^16.9.0"
      },
    

    工具統一

    這幾年VSCODE很火,微軟的開源貨可以說可圈可點。之前我用webstorm,其一不是免費,其二不見比VSCODE要好,其三我搞不定如何使用formatting/fix on save. 所以已經被我放棄。
    我建議一個團隊使用統一的工具,IDE、Plugins、配置等等。
    VSCODE下必須的三個插件:

    • Eslint
    • Prettier - Code formatter
    • GitlLens
      記得把ESlint的 Auto Fix On Save的選項選上

    項目下的ESlint安裝 (nextjs)

    網上教程很多,(也很亂!!!)用下面這個簡單版(不含airebnb,如果你真的那麼崇拜airebnb,請留言,我可以抽空加上)

    npm i --save-dev babel-eslint
    npm i --save-dev eslint
    npm i --save-dev eslint-plugin-react
    

    在根目錄下創建.eslintrc, 寫入下面內容:

    {
      "parser": "babel-eslint",
      "extends": ["eslint:recommended", "plugin:react/recommended"],
      "rules": {
        "react/react-in-jsx-scope": "off"
      },
      "globals": {
        "React": "writable"
      }
    }
    

    接下來,你可能會碰到Eslint報錯,比如missing prop validation console is not definded,等,你在根據需要來在代碼或者eslintrc裡調整。
    注意:不用裝eslint-prettier,vscode的prettier好像可以take care這些。記住不用選“integrate with eslint” 新版的prettier (2.2.2) 好像連這個選擇都沒了。

    发布在 React
  • Bitbucket SSH的問題

    有的東西看似很簡單,但是有時候你沒認真看,它會把你玩死。
    Bitbucket SSH的設置,設置好了,以後就不用輸密碼了。但是你設了,還是不行,為什麼?
    10有8,9, 你設錯地方了。

    一個是在repsoitory底下,這個是個read 用的,寫不了。

    Use access keys to gain read-only access to this repository. Learn more about using SSH keys.
    read-only, 我沒有注意到,同學們注意到了嗎?

    如果你是要加個可以寫的SSH key,那麼把這個刪除了,注意要刪除乾乾淨淨,就是不小心在其他repo裡加的要通通刪除了。然後在用戶設置裡(點左下角的頭像)設置SSH。

    祝你好運!

    发布在 笔记
  • Apollo client 緩存問題

    Apollo client 聲稱他們把緩存玩的很好,用過以後才知道其實不然。
    更新緩存,還是很手動的活。比如:

     <Mutation
              mutation={DELETE_CUSTOMPAGE}
              key={item.draftid}
              update={cache => {
                const { customPages } = cache.readQuery({ query: GET_CustomPages });
                const newCustomPages = [...customPages];
                const idx = _.findIndex(newCustomPages, {
                  id: item.id
                });
    
                if (idx > -1) {
                  newCustomPages.splice(idx, 1);
                }
    
                cache.writeQuery({
                  query: GET_CustomPages,
                  data: { customPages: newCustomPages }
                });
              }}
            >
    

    在同一個模塊,加這些cache處理還不算太麻煩,問題是另一個模塊要用到其他模塊,要保證其他模塊修改後,通知所有相關模塊也更新對於的QUERY是極其麻煩的。

    因此,有人問題這個問題 - 如何把緩存關閉:
    https://stackoverflow.com/questions/47879016/how-to-disable-cache-in-apollo-link-or-apollo-client

    其中一位大哥的答案(非選中的)解決了我的問題:

    I would always suggest not to disable inbuild caching feature from apollo client. Instead you can always set fetchPolicy: 'network-only' for an individual queries. Something like this

    <Query
        query={GET_DOG_PHOTO}
        variables={{ breed }}
        fetchPolicy='network-only'
    >
     {({ loading, error, data, refetch, networkStatus }) => {
       ...
     }}
    </Query>
    

    While fetching data with this Query, it would always do a network request instead of reading from cache first.

    发布在 笔记
  • RE: Array / Map /Object Transfer and Reshape Example

    Easier way

    const groupBy = (items, key) => items.reduce(
      (result, item) => ({
        ...result,
        [item[key]]: [
          ...(result[item[key]] || []),
          item,
        ],
      }), 
      {},
    );
    
    
    const pets = [
        {type:"Dog", name:"Spot"},
        {type:"Cat", name:"Tiger"},
        {type:"Dog", name:"Rover"}, 
        {type:"Cat", name:"Leo"}
    ];
        
    
    const result = groupBy(pets, 'type');
    console.log(result);
    
    发布在 笔记
  • Array / Map /Object Transfer and Reshape Example
    function groupBy(list, keyGetter) {
        const map = new Map();
        list.forEach((item) => {
             const key = keyGetter(item);
             const collection = map.get(key);
             if (!collection) {
                 map.set(key, [item]);
             } else {
                 collection.push(item);
             }
        });
        return map;
    }
    
    
    function strMapToObj(strMap) {
      let obj = Object.create(null);
      for (let [k,v] of strMap) {
        // We don’t escape the key '__proto__'
        // which can cause problems on older engines
        obj[k] = v;
      }
      return obj;
    }
    function objToStrMap(obj) {
      let strMap = new Map();
      for (let k of Object.keys(obj)) {
        strMap.set(k, obj[k]);
      }
      return strMap;
    }
    
    // example usage
    
    const pets = [
        {type:"Dog", name:"Spot"},
        {type:"Cat", name:"Tiger"},
        {type:"Dog", name:"Rover"}, 
        {type:"Cat", name:"Leo"}
    ];
    
    //use map to get new pets
    
        
    const grouped = groupBy(pets, pet => pet.type);
    
    const groupedObj = strMapToObj(grouped);
    
    
    
    
    // const groupedStr = JSON.stringify([...grouped]);
    // const groupedJson = JSON.parse(groupedStr);
    
    // console.log(JSON.stringify([...grouped]));
    // console.log(groupedJson);
    
    发布在 笔记
  • material-ui 如何運用主題的顏色

    如何在一個組件里使用主題顏色?
    如果你從Bootstrap CSS過來,你可能希望我們可以這麼寫:
    <p class="text-primary">.text-primary</p>
    寫成react就是這樣嘍:
    <p className="text-primary">.text-primary</p>
    很抱歉,這麼寫行不通!

    必須這麼弄:

    import { withStyles } from "@material-ui/core/styles";
    const styles = theme => ({
      paper: {
        position: "absolute",
        width: "90%",
        backgroundColor: theme.palette.background.paper,
        boxShadow: theme.shadows[5],
        padding: theme.spacing.unit * 4,
        outline: "none",
        height: "90vh",
        overflowY: "scroll",
        color: theme.palette.primary.main
      }
    });
    class YourComponent extends React.Component {
    ...
    }
    export default withStyles(styles)(YourComponent);
    
    

    material-ui 默認主題屬性可以在這裡查看:https://material-ui.com/customization/default-theme/

    发布在 笔记
  • 用moment庫轉換MySQL的毫秒級時間

    moment.unix(ts/ 1000).format("MM/DD/YYYY HH:mm")
    'ts' 是MySQL的datetime, 除以1000得到秒值,然後再格式化

    发布在 笔记