nereuseng

重新出發


  • 首頁

  • 歸檔

自己搭建React+Webpack開發環境並性能優化

發表於 2017-10-12 | 更新於 2018-06-10

引言

之前我的用fb的create-react-app來直接開發,直接用npm install,之後放到Heroku也是超級不用腦的XD 之後隨著自己越來越上手,發現自己src文件夾下跟我房間一樣亂(誤,想嘗試自己手把手搭建整個開發環境,順便把文件整理。

開始

一開始我看的文章是 [1]从零搭建React全家桶框架教程,根據他提供的指令搭建。下面是我看了他的文章,找出需要用到的元件指令,在專案根目錄下的cmd打上:

npm init
npm install --save-dev-g webpack    //新增webpack.config.js exports....
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0
    //新增babel文件 presets等等....
    //開始在Index.js寫react的東西
    //加上方便的指令
npm install --save react-router-dom
npm install webpack-dev-server --save-dev
npm install react-hot-loader@next --save-dev
npm install --save-dev css-loader
npm install --save-dev file-loader
npm install style-loader --save-dev
npm install --save-dev url-loader   //這是用來引入圖片
npm install axios

Webpack是用來打包各種文件,像是CSS、JS檔、Module、Babel、背景圖片等等,非常的好用!Babel組件把ES6,ES7的語法轉換成ES5,css-loader,file-loader,style-loader,url-loader都是webpack用來打包css、圖案的組件。

優化

在裝完各種檔案(Package.json、webpack.config.js、.babelrc我會放下面)後,再來做優化:

  1. npm dedupe[2](安裝檔案都需要)
    安裝完node package後,需要這個指令來重新整理,會發現node_modules文件夾會變小哦!

  2. CommonsChunkPlugin
    他會把大家共用的JS檔案拿出來,減少重複的檔案。

  3. UglifyJSPlugin
    會壓縮JS檔案,讓體積變小。

  4. 把React換成Production版本
    減少原本react中的註釋和空白。

    new webpack.DefinePlugin({
        'process.env': {
            NODE_ENV: JSON.stringify(process.env.NODE_ENV),
        },
    }),
    

經過這四招,我把檔案從快1MB減到300KB++,下面是我Webpack的檔案

Webpack設定檔

const path = require('path');
const webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

const srcPath = path.resolve(__dirname, 'src');
const distPath = path.resolve(__dirname, 'dist');

module.exports = {
    /*devtool讓我在borwser看到哪裡出問題*/
    devtool: 'cheap-module-eval-source-map',
    context: srcPath,
    /*入口*/
    entry: [
        path.join(__dirname, 'src/index.js'),
    ],  
    /*输出到dist文件夹,输出文件名字为bundle.js*/
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
    },

    /*src文件夹下面的以.js结尾的文件,要使用babel解析*/
    /*cacheDirectory是用来缓存编译结果,下次编译加速*/
    module: {
        rules: [
            {
                test: /\.js$/ ,
                loader:['babel-loader?cacheDirectory=true'],
                exclude: '/node_modules/'},
            {
                test: /\.jsx$/ ,
                loader:['babel-loader?cacheDirectory=true'],
                exclude: '/node_modules/'},

            {
                test: /\.css$/,
                exclude: /node_modules/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options : {
                            url: false
                        }
                    }
                ]},
            {
                test: /\.(png|jpg|gif)$/,
                exclude: /node_modules/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 25000
                    }
                }]    
            }]
    },

    devServer: {
        contentBase: path.join(__dirname, './dist'),
        historyApiFallback: true,
        host: '0.0.0.0',
        port: process.env.PORT || 8080,
        public: 'forecastapps.herokuapp.com'
    },

    resolve: {
        //bug of webpack:
        //https://github.com/webpack-contrib/css-loader/issues/74
        modules: ['./', 'node_modules'],
        alias: {
            images: path.join(__dirname, './dist/images'),
            owfont: path.join(__dirname, 'src/component/Forecast/owfont-master'),
            Api: path.join(__dirname, 'src/component/Api'),
            Today: path.join(__dirname, 'src/component/Today'),
            Forecast: path.join(__dirname, 'src/component/Forecast'),
            component: path.join(__dirname, 'src/component'),
            router: path.join(__dirname, 'src/router'),
        }
    },

    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: 'vendor.bundle.js',
        minChunks: 2
        }), 
        new UglifyJSPlugin(),
        new webpack.DefinePlugin({
            'process.env': {
            'NODE_ENV': JSON.stringify('production')
            }
        }),
    ],
};    

Package.json(一部分)

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev-build": "webpack --config webpack.config.js",
    "start": "set NODE_ENV=production&&webpack-dev-server --config webpack.config.js -p --progress --colors",
    "dev": "webpack-dev-server --config webpack.config.js --color --progress --hot",
}

.babelrc

{
    // compact用來蓋掉在compiler的時候,出現的"The code generator has deoptimised the styling of [some file] as it exceeds the max of "500KB" [3]"訊息
    "compact": "false",
    "presets": [
        "es2015",
        "react",
        "stage-0"
    ],
    "plugins": [
        "react-hot-loader/babel"
    ]
}

Hot Module Replacement

這邊我有不太明白的地方,就是關於Hot Module Replacement。Hot Module Replacement就是在我開發時,能在我保存後,更新我修改的那部分,不需要我手動刷新。但在使用後,發現一個問題:State每次在我保存後,會被重置。我嘗試了react-hot-loader,發現不知道怎麼弄QQ看有誰路過能指點一下XD

參考資料

  1. https://github.com/brickspert/blog/issues/1
  2. http://www.alloyteam.com/2016/03/master-npm/
  3. https://tutel.me/c/programming/questions/29576341/what+does+quotthe+code+generator+has+deoptimised+the+styling+of+some+file+as+it+exceeds+the+max+of+quot100kbquotquot+mean
  4. https://github.com/reactjs/redux/issues/809

Hexo 添加Keywords和提交Sitemap到Google的心得

發表於 2017-10-05 | 更新於 2018-06-10

發現我寫的文章無法在Google Search上出現,於是我找了相關的教程,以下是我當中的心得:

Keywords

首先我添加Keywords,是根據這個部落格的文章[1]來進行,在_config.yml找到 #Site,在#Site最下面添加Keywords: +你想要的Keywords,用逗號來分割:

keywords: Keywords,Google,Sitemap,SEO,Hexo

因為我用的是Next的主題,主題模板的更改已經完成,這邊不再細寫,可到上面的文章連接參考,最後到 blog根目錄/scaffolds/post.md,在模板上添加Keywords:

title: {{ title }}
date: {{ date }}
categories:
tags:
keywords:

Sitemap

我參考了這個文章[2],先在blog根目錄安裝npm插件

npm install hexo-generator-sitemap --save

再來到_config.yml添加代碼,若找不到關鍵字,請直接在_config.yml的最下面添加

sitemap:
path: sitemap.xml

注意path的更改 [3]

請檢查_config.yml中是不是尚未更改url,把下面的yoursite.com改成

url:http://www.yoursite.com

這個:

url:http://www.你在github或者其他地方的網址.com

改好後在Cmd的blog根目錄打入

hexo g
hexo d

並且在你的blog網域上查看
例如:https://nereuseng.github.io/sitemap.xml
就能看到我產生好的Sitemap

提交到Google Search Console

根據這篇文章[4],
我在索引(Crawl)——>Sitemap 新增Sitemap
並把路徑貼進去,就大功告成了!

參考資料

  1. http://www.yuanye097.com/2015/10/26/name/
  2. http://www.jianshu.com/p/8db494e9dffc
  3. https://github.com/hexojs/hexo/issues/705
  4. http://fionat.github.io/2016/04/02/sitemap/

React and Google Maps Api

發表於 2017-09-20 | 更新於 2018-06-10

前言

我知道現在在github上有現成的React Google Maps的套件,但是想透過這次的研究,了解google maps api是如何運作的,下次應該就直接用套件了吧XD

目標

在全屏的Google Maps地圖上,只要點擊地圖,取得地圖上的坐標,就能知道那個地點的天氣

熱身(Optional)

依照Google官網上的api文件[1],和Youtube上的教學影片[2],建立一個有基本版面的地圖

整合至React

依照這個網站[3]的文章,建立Component後,先在Render()建立一個想要放入地圖的Div,再來componentDidMount放入在上面寫的initMap function,並且在index.html加入Google Maps Api的Javascript,就能完成一個在React上的簡單地圖。

點擊增加Marker

目前的地圖是靜態提供Marker,根據Google Maps Api的文件[4],我改寫了當中的map.addListener,把上面提供new google.maps.Marker的方法加進去,這樣你的React地圖點擊就會有新的Marker了!

刪除舊有的Marker

根據文件[5],map.setMap(null)只能隱藏標記,也不能隱藏我點擊增加的Marker,參考了文件[6],在Component上面增加了兩個Global Variable:map和markers[],加上setMapOnAll、clearMarkers、deleteMarkers的function,就能完整的刪除標記了。

原理

利用增加Marker後,把Marker推到markers的陣列:markers.push(marker),再map.addListener中先刪除Marker,才再新增。

坐標與Open Weather Api整合

在原有的程式整合這個Component後,我在程式原有的State加上lat和lng來儲存從Google Maps Api從來的坐標,並且提供Component onClick={handleClick}的的Callback function,來接從Component收到map.addListener產生的坐標。這樣在收到坐標的改變後,顯示天氣的元件也會隨著改變。不過在串接天氣Api的過程中,有一個很奇怪的問題:

Axios api 無限loop

我一開始想說把抓到的坐標放到我的State,但卻一直無限loop,把this.setState的lat、lng拿掉之後,就沒事了,真的很怪異,不知道誰能幫我解答XD


    getLocationWeather(lat, lng, unit){
        this.setState = ({
            lat: lat,
            lng: lng
        }, () => {

        //結論:糾結了一整個下午,為什麼加了上面的setState會導致Infinity Loop呢?
            getLocationWeather(lat, lng, unit).then(weather => {
                this.setState ({
                    ...weather,
                    masking: true
                }); alert(JSON.stringify(this.state.city));  
            });
        });

        if (this.props.units !== unit) {
            this.props.onUnitChange(unit);
        }

        setTimeout(() => {
            this.setState({
                masking: false
            });
        }, 600)
    }

發現原因

原來我在setState後面多打一個等於


    this.setState = ({
            lat: lat,
            lng: lng
        }, () => { ...

this.setState變成一個新的function,執行後面getLocationWeather的程式後,呼叫this.setState,結果就變成死循環了

這個發生的原因!

結語

在和Huli大大聊過後,發現自己的作品還不完整,還能添加更多的功能,也看到其他人的天氣作品,覺得自己還有一段很長的路要走。歡迎各位一起討論!

DEMO

這裡

參考連接

  1. https://developers.google.com/maps/documentation/javascript/tutorial?hl=zh-tw
  2. https://www.youtube.com/watch?v=Zxf1mnP5zcw
  3. https://code.tutsplus.com/tutorials/getting-started-with-react-and-jsx--cms-27352
  4. https://developers.google.com/maps/documentation/javascript/events?hl=zh-tw
  5. https://developers.google.com/maps/documentation/javascript/markers?hl=zh-tw
  6. https://developers.google.com/maps/documentation/javascript/examples/marker-remove?hl=zh-tw

React一到兩週學習心得

發表於 2017-09-13 | 更新於 2018-06-10

在畢業後找工作的期間
發現大部分前端工程師
都需要熟悉任何一項的Javascript框架(AngularJS, VueJS, ReactJS)
於是我在一次的面試當中下定決心
從9月1號左右開始每天不間斷的學習

學習的的資源
除了Youtube上的影片
也包含之前在ptt po的清大線上課程
這邊我要感謝清大的教授
講解的非常清楚外
提供那麼好的免費線上資源

我目前的Check List:

  1. 手刻的CSS版型(包含Nav Bar,但不含他的RWD)
  2. HTML表單的Input
  3. Ajax使用與Api串接(只用到Axios,不包含Google系列)
  4. State和Props的差別

學習TODO list:

  1. Nav Bar的RWD
  2. Promise資料的Exception
  3. Ajax—fetch的使用
  4. Redux的概念
  5. Google系列的Api串接
  6. 重新學好JS
  7. 利用Nodejs當後台
  8. JQuery
  9. DOM

學習的途徑:

  1. 台大訓練班(JS)
  2. 書本(JS優良部分、Speaking Javascript)
  3. 清大線上課程(Redux)
  4. Youtube上的開發者學堂

學習TODO list(長期):

  1. CS50
  2. 清大演算法(江蕙如老師)
  3. Lavarel
  4. 能完成那樣的作品(https://www.ptt.cc/bbs/Soft_Job/M.1433644651.A.976.html)

列了那麼多
而且也不小心也把
React以外的技能列出來(還偷渡了PHP XD)
發現還有很多地方是不足的!
希望我能把基礎打好
這樣學習才會更快!

Hello Hexo!(更新問題發生原因2017/10/05)

發表於 2017-09-09 | 更新於 2018-06-10

今天H大的提點下,我小心翼翼的開了我人生中第一個用npm架好的framework。
之前心得都是放在Blogspot,所以自己架站還蠻新奇的。
雖然說剛剛很崩潰


大坑

才想要發文章,就一定發現一個大坑:
使用以下指令:

hexo new "Hello Hexo!"

結果出現了這樣的輸出:

INFO  Created: c:\xampp\htdocs\blog\nereuseng\source\_posts\undefined Hexo.md

系統崩潰

我不管他,繼續用hexo generate,系統就開始跑不動了:

INFO  Start processing
ERROR Process failed: _posts/undefined Hexo.md
ValidationError: `slug` is required!
at ValidationError.WarehouseError (c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\error.js:17:11)
at new ValidationError (c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\error\validation.js:14:18)
at SchemaTypeString.SchemaType.validate (c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\schematype.js:107:11)
at SchemaTypeString.validate (c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\types\string.js:45:45)
at Array.<anonymous> (c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\schema.js:161:23)
at Schema._applySetters (c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\schema.js:305:13)
at Model._insertOne (c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\model.js:190:10)
at c:\xampp\htdocs\blog\nereuseng\node_modules\warehouse\lib\model.js:214:17
at tryCatcher (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\util.js:16:23)
at c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\using.js:185:26
at tryCatcher (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:512:31)
at Promise._settlePromise (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:569:18)
at Promise._settlePromise0 (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:614:10)
at Promise._settlePromises (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:693:18)
at Promise._fulfill (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:638:18)
at PromiseArray._resolve (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise_array.js:126:19)
at PromiseArray._promiseFulfilled (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise_array.js:144:14)
at Promise._settlePromise (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:574:26)
at Promise._settlePromise0 (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:614:10)
at Promise._settlePromises (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\promise.js:693:18)
at Async._drainQueue (c:\xampp\htdocs\blog\nereuseng\node_modules\bluebird\js\release\async.js:133:16)

解決方法

在生成Undefined Hexo.md的時候,應該要先更改檔案的名稱
Example:

Undefined Hexo.md -> Hexo.md

更新

之所以會發上面出現Undefined的事情,是因為我在_config.yml做了一件蠢事,我在

# Writing
new_post_name: :Hello Hexo # File name of new posts
default_layout: post
...

寫下了那些東西,導致Hexo無法正確產生新的md檔案,後來我改成這樣就沒問題了:

# Writing
new_post_name: year-:month-:day-:title.md # File name of new posts
default_layout: post
...

重新命名後按generate就沒問題了!
這是我的小小心得,希望大家也能和我分享!

自學PHP + MariaDB 後在Heroku平台Deploy心得

發表於 2017-08-27 | 更新於 2018-06-10

之前報名了一個學習PHP+MYSQL課程
教你怎麼寫前後端
並把它們連起來
後來想把寫好的作品放到Heroku
開始了折磨人的Heroku辛酸史(啊啊啊啊啊啊

1.

一開始由於是自學
沒有用Composer之類的套件管理(蝦米!?
安裝好Heroku後直接Push到Git根本沒辦法過
於是學會了裝Composer(相關網站我找不到了可以自己google)
再學習Composer install的指令
至於Composer.json的內容物我是用下面這個網址:
https://goo.gl/wdtwCh
然後才能成功的加上composer.lock

2.

再來是遇到Routing的問題
我沒有Procfile這個文件
我是依照這個網址設定:
https://goo.gl/WJ5LbL
內容物是web: vendor/bin/heroku-php-apache2 web/

Note: 記得你的檔案如果都放在web文件下,後面要加上web/這段字!
參考資料: https://goo.gl/uBeaeX

3.【failed to create symbolic link ‘/app/.heroku/php/php’: File exists】
再來也遇到這個問題
應該是之前不小心多裝了其他Buildpack
導致重疊的問題
依照最下面comment的指示把所有Buildepack重裝就好
參考資料:https://goo.gl/SNxhf5

4.

我終於成功push到git上了耶耶耶!!!
但是發現資料庫根本沒連好
於是在Heroku上裝了JawsDB MariaDB的addon (還要填信用卡資料orz)
根據它的Dashboard上的資訊用HeidiSQL連上
最後鬼打牆了好久才發現其中一個亂碼的Database
是他分配給我的
參考資料:https://goo.gl/bphuw9

我還一直鬼打牆怎麼不能Create Database
P.S : 我這邊真的卡了超久超想放棄的
後來在HeidiSQL導入你之前的資料後
資料庫就能開始使用了

心得:
沒有仔細看官方文件真的會出很多問題
下次提醒我自己要記得看

祝大家能從我的經驗解決你的問題!

12

nereuseng

這是我記錄我程式能力成長的地方,目前集中在React, JavaScript等,歡迎來交流!

16 文章
1 標籤
© 2018 nereuseng
由 Hexo 強力驅動 v3.4.4
|
主題 — NexT.Muse v6.3.0