Webpack配合Express項目開發

本文基于工作項目開發,做的整理筆記
在某個節點,想嘗試一下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

webpackAndExpress.png

我用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.jswebpack.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-serverUsing react-hot-loader with a webpack-dev-server and a node server

題外話,這個項目的sass里,我還想使用susy去做柵格化布局,代替bootstrap的這一部分。webpack安裝使用susy也非常方便,研究好了也會做一個筆記。

到這里,就先結束了。


學習是一條漫漫長路,每天不求一大步,進步一點點就是好的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容