本文基于工作項目開發,做的整理筆記
在某個節點,想嘗試一下node,擺脫jsp的java前端方式,就切換到了Express框架,后臺依然是java提供API,但是前端再也不用寫java的controller、jsp頁面了。Good。之前用gulp做sass、js的打包壓縮,現在也想整理下項目的結構,用上慢慢熟悉的Webpack。本文就是做個筆記,兩者如何配合使用。
前提條件:
你已經了解基本的Webpack知識和nodejs的Express。
關于Webpack,可閱讀:Webpack初學者使用教程。
關于Express,晚些時候才會寫一篇,你可以先去谷歌一下(本文對Express只是一帶而過)。
編碼環境:
系統:OS X EI Capitan
版本:10.11.6
我用Webpack做什么
在這里,我的需求很簡單。我只是想要webpack幫我做2件事:
- 合并、打包、壓縮成多個js
- 將sass轉換成css,并打包成一個單獨的css文件
如果你的需求和我不太一樣,這篇文章可能不太適合你。不過歡迎你閱讀并給予指導,謝謝。
先看一下項目結構
我們先看一下原來的項目結構(不帶webpack),然后再看一下webpack將用在哪里。
myProject
| - app
??| - controllers
??| - models (如果不連接數據庫,純粹調用API接口,這個就沒有)
??| - schemas (如果不連接數據庫,純粹調用API接口,這個就沒有)
??| - views
| - bin
??| - www
| - config
??| - config.js
| - node_modules (項目所需模塊)
| - routes
??| - routes.js
| - static
??| - build
??| - fonts
??| - images
??| - js
??| - sass
| - test
| - app.js
| - package.json
我的大概就這么多,省略掉了部署時pm2的配置文件process.json,還有一些log文件。如果你還有用bower管理jquery,bootstrap等可能會有.bowerrc,bower.json。如果你還用了git可能會看到.gitignore文件。如果你還有用...
這篇文章的目的就是重做static(靜態文件)這一塊內容,將webpack整合進來,讓它為我們的項目服務。所以static文件夾的結構將會變成下面這個樣子。(其他文件都沒有改變,包括app.js)
| - static
??| - build (打包出來的js、css放這里)
??| - fonts
??| - images
??| - node-modules (項目所需模塊)
??| - js
??| - sass
??| - package.json
??| - webpack.config.dev.js
??| - webpack.config.prod.js
開發時如何使用呢
我前面說了,我不去改變原有的express項目結構。只是重新構建static文件夾,改變它的內容,webpack僅僅在這里面起作用,完全不會影響到外面。在開發的時候,你可以選擇兩種使用方式:
每次js或sass文件改動,就執行打包,重新生成一次。
只需要穩定跑起express應用服務,然后不斷的對靜態文件打包、打包、打包...跑起一個express應用服務,再跑起一個webpack的server。
開發時,修改頁面的引用,比如說
<link rel="stylesheet" href="http://localhost:8080/styles.css">
<script type='text/javascript' src='http://localhost:8080/main.js'></script>
(其中,localhost:8080是webpack dev server)
若使用后者的方式,就需要在部署時,修改相關引用文件的路徑。
這里,可以做一個變量,根據NODE_ENV是不是為dev,自動去做不一樣的路徑引用。
你可能會說這什么方法,好像不是很好。有沒有更好的方法呢?
很抱歉的說,目前,我只是用這個方法。我在谷歌上搜了一些其他方法,有些我弄到最后都沒有成功,也許是我哪里配置錯了;有些是覺得操作起來好繁瑣,代碼有需要混在node那邊,幾個引用幾個配置。如果nodejs的express本身不是非常熟悉的話,感覺一團亂。(到時候想丟掉webpack,又有點懵逼)
選擇這樣一個方式,還是有些好處的,比如說:
- express那邊是express,靜態資源webpack這邊就是webpack兩邊不影響。我想丟掉webpack,去用gulp、去用grunt,輕輕松松。或者我就是丟掉,什么都不用了。
- 也是因為上面這個原因,代碼更清晰。別人上手或者接手項目進行開發,也非常容易。
相關命令跑起webpack
這篇文章并不是去關注express如何用的,你可以谷歌搜索閱讀相關文章。Express這個我還沒有整理出來,我也是個菜鳥??????,晚些我再學習學習,整理一篇。
關于webpack的配置,你可以閱讀我之前的一篇筆記:Webpack初學者使用教程,這里不會詳細的介紹了。
這里對跑起webpack的命令重復一遍。首先你要進入到static文件夾,為它生成一個package.json:
$ npm init
然后我們安裝一遍需要的模塊,命令如下:
$ npm install -g webpack webpack-dev-server (如果你全局沒有安裝的話,跑一下)
$ npm install --save-dev webpack style-loader css-loader sass-loader node-sass
$ npm install --save-dev extract-text-webpack-plugin webpack-dev-server
然后我們去創建webpack.config.dev.js
,webpack.config.prod.js
,并修改相應內容,如下:
$ touch webpack.config.dev.js webpack.config.prod.js
下面是webpack.config.dev.js的內容:
// webpack.config.dev.js
var path = require('path')
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
devtool: 'cheap-eval-source-map',
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/dev-server',
'./js/index'
],
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new ExtractTextPlugin("styles.css")
],
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css!sass')
}
// 看到這個注釋了么,額外提一點
// 如果你在 sass那里用了susy,你就必須用上面的寫法;如果沒有用,可以使用下面這種寫法
// {
// test: /\.scss$/,
// loader: ExtractTextPlugin.extract('style-loader', 'css-loader', 'sass-loader')
// },
]
},
devServer: {
contentBase: './build',
hot: true
}
}
下面是webpack.config.prod.js的內容:
// webpack.config.prod.js
var path = require('path')
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
devtool: 'source-map',
entry: ['./js/index'],
output: {
path: path.join(__dirname, 'build'),
filename: 'bundle.js'
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
minimize: false,
compressor: {
warnings: false,
},
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new ExtractTextPlugin("styles.css"),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
],
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css!sass')
}
]
}
}
然后我們去package.json中加兩個script,簡化一下跑起server和打包文件的命令。如下:
...
"scripts": {
"build": "webpack --config webpack.config.prod.js",
"dev": "webpack-dev-server --config webpack.config.dev.js"
},
...
之后,只要通過下面的命令就可以執行:
$ npm run dev (跑dev server)
$ npm run build (跑build production,進行打包)
好了,開發的時候,可以盡情的玩耍了。
是否還有疑問
會不會對webpack在這里的這種使用方式,還有疑問?“什么!webpack就用在static這里,而且僅僅是在這里而已。有沒有一個更好的解決方案,一句命令跑起nodejs的同時,順便可以帶起來webpack,跑起一個webpack-dev-server。也就是說,簡單的在app.js里引用webpack-dev-middleware,webpack-hot-middleware,加幾句代碼去搞定它。
這里,我也希望有更好的方式。暫時,我就是用上面那個方式開發。
我之前也閱讀了相關文章,比如在express服務中搭建webpack-dev-server,Using react-hot-loader with a webpack-dev-server and a node server。
題外話,這個項目的sass里,我還想使用susy去做柵格化布局,代替bootstrap的這一部分。webpack安裝使用susy也非常方便,研究好了也會做一個筆記。
到這里,就先結束了。
學習是一條漫漫長路,每天不求一大步,進步一點點就是好的。