Giter VIP home page Giter VIP logo

express-webpack's Introduction

项目初衷
  • 这个项目主要是对公司原来的官网进行重构。 官网构成很简单,几个展示页面,共用footer,header,手机端和电脑端采用了两套页面,旧版官网是前后端不分离的,使用jsp来构建页面,通过java中的action文件来判断手机还是电脑访问,以及传递数据到jsp进行渲染。
  • 对于官网来说,使用jsp渲染有利于SEO,服务端渲染速度也会相对快一些。但是对于前端来说,在构建官网的时候,除了要写基本的前端代码,还要写一些jsp代码,还要在java的action里面写一些java代码,旧版官网在后端小伙伴的帮助下勉强完成了。考虑到后期招新人官网越来越难以维护,以及对express神往已久,以及用不惯idea及eclipse,所以趁着工作不太忙进行了这次项目重构。
  • 结合node,同样实现了在服务端渲染页面,而且某种意义上也算是实现了前后端分离,前端通过node调用后端提供的api,项目更容易维护了。
项目结构

我的项目结构

  • bin文件夹参考了express-generator 用来启动http服务
  • app.js 用来配置模板引擎,日志打印,开发模式下热更新,引入路由等
  • routes中的app.js 配置路由(由于页面不太多且只有几页需要获取接口,所以把路由放在一个文件了,也可以每页一个路由文件)渲染页面,model.js调取后台接口,生成渲染数据
  • src存放前端css,js,图片等
  • views存放渲染html
  • public存放webpack编译之后的静态文件
使用supervisor监测文件修改自动重启

scripts

-w 后面是要监控的文件夹或js文件,
-e 后面是要监控的文件扩展名默认是node,js

为了使项目结构更加清晰,我把pc的资源和mobile的资源分别放置在了不同的文件夹中,pc和mobile下同一页面我采用了同一命名,为了便于在webpack进行编译时读取入口文件和打包到对应的文件夹,我在package.json的scripts里面分别对pc和mobile下的资源进行开发过程中的start和和开发结束后的production。production是将文件进行webpack发布模式下的编译,编译之后文件会打包到public文件夹中,我这种方式,需要在发布代码之前,分别执行npm run production-pc和production-mobile命令,进行两次编译。

开发模式下的webpack无刷新更新

使用webpack-dev-middleware和webpack-hot-middleware实现浏览器的无刷新更新。

  • webpack-dev-middleware (https://github.com/webpack/webpack-dev-middleware)
    webpack-dev-middleware输出的文件存于内存中,定义了webpack.config.js,webpack就能根据配置项构建出entry和ouput模块的关系,webpack-dev-middleware在此基础上形成一个文件映射系统,每当应用程序请求一个文件,它匹配到了就把内存中缓存的对应的结果以文件的格式返回给你,反之就进入下一个中间件。
  • webpack-hot-middleware(https://www.npmjs.com/package/webpack-hot-middleware)
    webpack-hot-middleware webpack-hot-middleware结合webpack-dev-middleware可以实现浏览器的无刷新更新
    需要同时在entry里引入"webpack-hot-middleware/client" (webpack.entry.js)
   var hotMiddlewareScript = 'webpack-hot-middleware/client';
   entry[file] = [filePath + '/'+file+'/app.js',hotMiddlewareScript];

参考代码如下:(根目录app.js)

if (isDev) {
 var webpack = require('webpack'),
     webpackDevMiddleware = require('webpack-dev-middleware'),
     webpackHotMiddleware = require('webpack-hot-middleware'),
     webpackDevConfig = require('./build/webpack.config');
 var compiler = webpack(webpackDevConfig);
 app.use(webpackDevMiddleware(compiler, {
   publicPath: webpackDevConfig.output.publicPath,
   noInfo: true,
   // 这里强制将html文件写入(需要为编译后的html文件设置模板引擎)
   writeToDisk: (filename) => {
     return /\.html$/.test(filename)
   },
   stats: {
     colors: true
   }
 }))

 app.use(webpackHotMiddleware(compiler));
 require('./routes/app')(app);
} 
  • 在发布模式,只需要使用express.static来使用相应的静态资源(根目录app.js)
    app.use(express.static(path.join(__dirname, 'public/pc')));
    app.use(express.static(path.join(__dirname, 'public/mobile')));
    // 引用相应的路由文件
    require('./routes/app')(app);
路由及模板引擎的设置
  • 在项目中通过node调取后端服务,为了方便我采用了axios (routes/model.js)
model.getPositions = function(callback) {
    return axios.get(model.baseUrl + 'rest/position/page', {
        params: {
           
        }
    }).then(response => {
        if(response.data.code === 200){
           // ...
        }
        callback && callback();
    }).catch(e => {
        callback && callback();
    });
}
  • 在(router/app.js)里面配置路由,根据访问设备,分别跳转到手机端和pc端网页,并且在渲染view的时候将服务器数据传递到view
router.get('/', function (req, res, next) {
    model.getNewsList();
    next();
}, function(req, res, next) {
    if (isMobile(req)) {
        res.render(mobileViewPath + '/index', { baseMsg: model.baseMsg, allNews: model.allNews});
    } else {
        res.render(viewPath + '/index', { baseMsg: model.baseMsg, rollNewsList: model.rollNewsList });
    }
});
  • 在view中使用ejs来渲染数据,这就需要我们给view设置模板引擎。这里有个问题就是我们的项目中的views文件夹是开发过程中的,最终要将它们通过webpack打包到public文件夹中,这样的话,最终部署的时候我们不再需要views文件夹只上传public文件夹就可以了,所以最终node端用模板引擎渲染的是public中打包后的文件。即需要把public文件夹中的html设置为ejs模板引擎。
    (app.js)
// view engine setup
app.engine('html', ejs.__express);
app.set('views', path.resolve(__dirname, 'public/pc/views'));
app.set('views', path.resolve(__dirname, 'public/mobile/views'));
app.set('view engine', 'html');

这里有一个问题就是使用"html-webpack-plugin",在template选项中默认template使用ejs模板引擎,这样的话在views文件夹中写ejs模板引擎会直接被渲染,并且我们设置的路由渲染页面是public中的html,所以在views中会拿不到服务端传递数据而报错,我这里修改了template的模板引擎为handlebars,这样的话在webpack编译的时候就会默认忽略掉ejs代码,在public中保留了ejs代码

       let opts = {
        inject: 'body',
        filename: 'views/'+file + '.html',
        template:'handlebars-loader!'+(templatePath + file + '.html'),
        chunksSortMode: 'manual',
        chunks: [file],
        hash: true,
    }

webpack的配置这里就不说了,都是一些常规的配置。

使用pm2及nginx进行部署
  • 在服务器上安装node,安装pm2
  • 将项目中的(routes public bin app.js packge.json(删除掉了devDependencies),bin)拷贝到服务器相应目录,在项目根目录安装依赖,并且在该目录下启动pm2(pm2 start ./bin/www),这样就可以通过服务器ip加相应端口号访问项目了
    pm2常用命令
      pm2 start ./bin/www    # 启动node服务
      pm2 start ./bin/www --name home-satrt # 命名进程
      pm2 list               # 显示所有进程状态
      pm2 monit              # 监视所有进程
      pm2 logs               # 显示所有进程日志
      pm2 stop all           # 停止所有进程 
      pm2 restart all        # 重启所有进程
      pm2 reload all         # 0 秒停机重载进程 (用于 NETWORKED 进程)   
      pm2 stop 0             # 停止指定的进程
      pm2 restart 0          # 重启指定的进程
      pm2 startup            # 产生 init 脚本 保持进程活着 [pm2 startup systemd (开机自启) ]
      pm2 web                # 运行健壮的 computer API endpoint (http://localhost:9615)
      pm2 delete 0           # 杀死指定的进程
      pm2 delete all         # 杀死全部进程
    
  • 配置nginx,如果服务器没有装nginx需要先进行安装
    常用命令
      nginx -t        #检测nginx配置文件是否正确
      nginx           #nginx启动
      nginx -s stop   #nginx关闭
      nginx -s reload #nginx平滑重启
    
  • 修改nginx配置文件
   upstream test {
       server 127.0.0.1:3000;
       keepalive 64;
   }
   server {
       listen 80;
       server_name aaa.XXX.com
       root /data/www/home/dwt-gw;
       location / {
         # Proxy_pass configuration 
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
         proxy_set_header Host $http_host; 
         proxy_set_header X-NginX-Proxy true; 
         proxy_http_version 1.1; 
         proxy_set_header Upgrade $http_upgrade; 
         proxy_set_header Connection "upgrade"; 
         proxy_max_temp_file_size 0; 
         proxy_pass http://test/; 
         proxy_redirect off; 
         proxy_read_timeout 240s; 

       }
   }

然后启动nginx,根据所配置的server_name就可以访问相应项目了

express-webpack's People

Contributors

catyee avatar surround000 avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.