本文基于工作项目开发,做的整理笔记
在某个节点,想尝试一下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也非常方便,研究好了也会做一个笔记。
到这里,就先结束了。
学习是一条漫漫长路,每天不求一大步,进步一点点就是好的。