會在主題這樣寫 代表我建立的方式稍微不同
首先 我是已經有整個做完 React js 101 這一個中文教材之後(除了Server Side Render),才開始做做我自己的專案,這是一個很用心的教材 推薦大家可以去那邊練功
然後,還有一件事情是,我打這一篇文章的時候 我的專案已經走了一個禮拜 所以我是盡力回想我前面遇到的問題 如果我後面有想到 文章會再提到
好,我的出發點很簡單
REDUX & MATERIAL UI 這裏
我喜歡的首頁 這裏找
找好了之後,我們就開始囉
首先我們先來改他 webpack.config 的設定((我盡量比對我改的到底要做什麼
new HtmlWebpackPlugin({
template: 'src/index.ejs',
minify: {
removeComments: true,
collapseWhitespace: true
},
inject: true
})
我是覺得副檔名很醜,所以 template: 'src/index.html
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loaders: ['babel']},
然後呢 loader 他test裡面只放.js,but 我參照官網建議都改.jsx,所以呢~
module: {
loaders: [{
test: /\.jsx$|\.js$/,
exclude: /node_modules/,
loaders: ['babel']
}, {
好 我module 總共多了另外3個loader 分別是json & bundle & jquery
module: {
loaders: [{
test: /\.jsx$|\.js$/,
exclude: /node_modules/,
loaders: ['babel']
}, {
test: /\.eot(\?v=\d+.\d+.\d+)?$/,
loader: 'file'
}, {
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url?limit=10000&mimetype=application/font-woff"
}, {
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url?limit=10000&mimetype=application/octet-stream'
}, {
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url?limit=10000&mimetype=image/svg+xml'
}, {
test: /\.(jpe?g|png|gif)$/i,
loader: 'file?name=[name].[ext]'
}, {
test: /\.ico$/,
loader: 'file?name=[name].[ext]'
}, {
test: /(\.css|\.scss)$/,
loaders: ['style', 'css?sourceMap', 'postcss', 'sass?sourceMap']
}, {
test: /\.json$/,
exclude: /node_modules/,
loader: 'json-loader'
}, {
test: /\.bundle\.js$/,
use: 'bundle-loader'
}, {
test: require.resolve('jquery'),
loader: 'expose?jQuery!expose?$'
}]
三個的原因我先解釋,你遇到就可以解決
首先 你要把 webpack 包的東西都想成一個一個scope 所以不管你是在哪裡import jquery 像是天真的以為 index.html or react.js start page 那個都是不會成功的 所以不要浪費時間
然後請先把剛剛講的bundle loader準備好
再來 npm install jquery --save
然後在你要用的component 那裡這樣處理 import 'jquery';
// Initial Library
import React from 'react';
import ReactDOM from 'react-dom';
import {
Link
} from 'react-router';
// 多國語言套件
import {translate} from 'react-i18next';
import 'jquery';
import OwlCarousel from 'react-owl-carousel2';
像我這邊就是要用 react-owl-carousel2
好 然後呢 網路上有一個解法是寫說在 webpack.config 加上
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
"root.jQuery": "jquery"
}),
加上這一段,然後就是一片美好 build 就可以動了
好,然後我們來談談大家都會用到的多國語言
首先 i18n 安裝就不教了 要複製貼上的部分 請自己Google
你裝回來之後 如果你不用 webpack
你可以照著這個範例過得很開心 Here
但是呢 這是不切實際的 因為你早晚要面對上線
所以囉 我們來談談我遇到的坑
安裝後 把json loader 也給他裝好
再來 照著剛剛我們貼的範例 把你的 多國語言資料夾建立起來 & common.json 檔案也要建立
再來就是坑 打開我的 i18n.js
i18next
.use(XHR)
.use(LanguageDetector) // 偵測瀏覽器語系
.init({
fallbackLng: 'en', // 未偵測到時的後備語系
ns: ['common'], // 語系的 loading namespace 如語系檔案名稱 common.js
// defaultNS: 'common', // 預設的 namespace name
// debug: true,
// interpolation: {
// escapeValue: false // not needed for react!!
// },
backend: {
// 設定語系檔案的 server 路徑, 會以GET的方式跟 server 要檔案
// lng = 語系代碼 ns = namespace
// loadPath: "/languageConfig/{{lng}}/{{ns}}.json"
loadPath: "{{lng}}",
parse: (data) => data,
ajax: loadLocales
}
}, (err) => {
console.log(err);
});
註解的地方就是快樂版本 沒有要用Webpack
然後你要用Webpack的話 千萬不要照大部分網路上教的 從頭到尾都找不到你的語系檔案
請把你的loadLocales Function改成下面這樣
import i18next from 'i18next';
import XHR from 'i18next-xhr-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
function loadLocales(url, options, callback) {
try {
let lng = window.navigator.languages[0];
console.log(lng);
let waitForLocale = require('bundle!./' + lng + '/common.json')
waitForLocale((locale) => {
callback(locale, {
status: '200'
});
})
} catch (e) {
callback(null, {
status: '404'
});
}
}
重點在於 let waitForLocale 那一段 記得要有common 然後 前面是沒有資料夾的那一層!
最後 不要用他的 LanguageDetector 現在的User 大部分都只會換Chrome 的語言排序
所以囉 不要用工程師的專業眼光看待他們 用順序來決定語系 他們就會覺得 真好用呢~
好囉 明天我們就可以用用看Redux 框架的實作感囉~