這裏提供手動搭建vue單頁面開發生產環境,並使用node寫後臺代碼,僅供小白參考;
代碼雖然沒多少,但牽扯的知識不少,須要逐個研究;
後續內容《手動搭建vue+node單頁面(二)》
https://segmentfault.com/a/11...javascript
項目地址:https://github.com/liubingyan...css
內容提要:vue2,webpack,express,router,jsonp,這一章會從0到開發環境,生產環境的搭建:html
思路: 先實現webpack單頁面的demo -> 而後實現express服務下的開發環境 -> 再實現開發·生產環境的切換 -> 最後作業務相關的頁面和後端開發
1、建立項目:
1.初始化項目:在桌面新建文件夾test,在test目錄下命令行輸入npm init -y;
2.test下建立src文件夾(前端全部代碼);
build文件夾(打包相關的webpack配置文件);
service文件夾(存放後端代碼);
data文件夾(存放json數據);
server.js(node服務)前端
2、下面咱們先作單頁面,先無論服務的事情
在src目錄中建立views(存放全部.vue組件),router(存放前端路由配置),store(存放vuex配置),man.js(單頁面入口文件),app.vue(單頁面首頁組件),test下建立index.html做爲載體。vue
接下來要作幾件事完成單頁面demo:
(1)編寫入口文件main.jsjava
//main.js const Vue from 'vue' const App from './app' new Vue({ el:'#app', render:h=>h(App) })
(2)單頁面主體app.vue;node
//app.vue <template> <div> {{msg}} </div> </template> <script> export default{ data(){ return { msg:'this is my app!' } } } </script> <style lang='less'> </style>
(3)接下來是配置文件:在build文件夾中建立webpack.config.jswebpack
//webpack.config.js const path = require('path') module.exports = { mode:'development',//webpack4新加的,不寫會報黃 entry: { main: path.resolve(__dirname, '../src/main.js') }, output: { path: path.resolve(__dirname, '../dist'), publicPath: 'http://localhost:3000/', filename: '[name].js' }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader', options: { loaders: { 'less': [ 'vue-style-loader', 'css-loader', 'less-loader' ] } } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },] }, resolve: { alias: {//開發環境使用vue.esm.js',官網有說明 'vue$': 'vue/dist/vue.esm.js' }, //reuqire加載文件會自動爲如下後綴的文件(如:./app.vue能夠寫成./app了) extensions: ['*', '.js', '.vue', '.json'] }, }
接下來就是要啓動項目了,不過要先安裝各類插件git
vue vue-loader webpack css-laoder sass-loader vue-style-loader babel-loader ````
不全,缺什麼根據提示慢慢裝github
應爲最終咱們啓動項目是用server.js啓動,因此在這裏咱們這樣寫
//server.js const webpack=require('webpack') const webpackConfig=require('./build/webpack.config') webpack(webpackConfig,function(err,stats){ if(err) throw err //輸出打包信息(不用在乎這些細節) process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n\n') })
而後執行打包(在test目錄下)
node server
爆紅就好好看看是語法錯誤仍是少插件,一下子就能解決。
看下效果,忘記,index.html要先寫成:
//index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id='app'></div> </body> </html> <script type="text/javascript" src="./dist/main.js"></script>
打開index.html看看效果。
3、開始實現express啓服和熱加載
接下來用express啓服,同時實現webpack的熱加載和server.js的熱加載;
1.修改配置server.js
//server.js const webpack=require('webpack') const webpackConfig=require('./build/webpack.config') //dev和hot用來實現前端的熱加載 const webpackDevMiddleware = require('webpack-dev-middleware') const webpackHotMiddleware = require('webpack-hot-middleware') const express=require('express') const path=require('path') const app=express() const compiler = webpack(webpackConfig)//刪除了打印的回調函數,加上的話這裏會執行兩遍打包,不曉得爲啥 app.use(webpackDevMiddleware(compiler,{ // public path should be the same with webpack config //在項目中這樣的路徑都會配置到統一的文件中 publicPath: 'http://localhost:3000/', noInfo: true, stats: { colors: true } })) app.use(webpackHotMiddleware(compiler)) app.listen(3000,function(){ console.log('App is now running on port 3000!'); })
2.修改兩個地方:webpack配置和index.html
// webpack.config.js const path = require('path') const webpack=require('webpack') const htmlPlugin=require('html-webpack-plugin') //增長頁面熱加載字段,添加到entry中(固定寫法) const hotMiddlewareScript = 'webpack-hot-middleware/client?reload=true' module.exports = { mode: 'development', entry: { //就是這樣寫就對 了 main: [path.resolve(__dirname, '../src/main.js'),hotMiddlewareScript] }, output: { path: path.resolve(__dirname, '../dist'), publicPath: 'http://localhost:3000/', filename: '[name].js' }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader', options: { loaders: { 'scss': [ 'vue-style-loader', 'css-loader', 'less-loader' ] } } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, ] }, resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' }, extensions: ['*', '.js', '.vue', '.json'] }, //新增html插件,生成main.js的同時生成index.html plugins:[ new htmlPlugin({ template:'index.html' }), //熱加載須要使用這個插件才起做用 new webpack.HotModuleReplacementPlugin(), ] }
而後index.html改動就是刪除本身寫的script標籤就好。
3.啓動項目以前全局安裝一個插件:(前端有了熱加載,這個是爲了後端的熱加載,修改服務或者打包配置文件不用手動重啓服務。)
npm i supervisor -g
而後修改package.json中的scripts
//package.json "scripts": { "test": "echo \"Error: no test specified\" && exit 1", //這句話是說:監控(-w)後定義的文件或者文件夾 -e表示-w監控的文件夾中的js文件發生變化時重啓server.js "start": "supervisor -w server,build,server.js -e js server"
},
4.接下來激動人心的時刻,啓動:
npm run start
打開localhost:3000
按下f12看看有沒有報錯,噹噹噹當,沒有報錯,如今已經完成了一個簡單但功能完善的開發環境;
4、署下生產環境
部署生產環境咱們要作幾件事:
1.build新建config.js,配置一些通用設置;
2.build新建webpack.config.dev.js,區分開發模式和生產模式的配置,其實能夠寫在一個文件中,弊端就是代碼太長,並且開發模式require()的組件比較多,生產模式不必加載,因此分開;
3.修改server.js,webpack.js和package.json文件;
咱們先修改package.json
//經過設置node環境中process.ENV屬性,來告訴webpack和server應該運行在哪一個環境,cross-env NODE_ENV就是用來設置process.ENV的; //package.json "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "supervisor -w server,build,server.js -e js,html server", "dev": "cross-env NODE_ENV=development supervisor -w server,build,server.js -e js,html server", "pro": "cross-env NODE_ENV=production node server" },
cross-env須要安裝下
npm i cross-env -save
再運行開發環境就用npm run dev ,生產就用npm run pro
接下來在build文件夾下建立並配置config.js
//config.js //簡單配置夠用就好,完整的配置能夠到vue全家桶中學習 const path=require('path') let isdev=process.env.NODE_ENV=='development'?true:false let config={ isdev:isdev, publicPath:'http://localhost:3000/', port:'3000' } module.exports=config
在build下建立並編輯webpack.dev.config.js(把以前的webpack.config.js複製一下)
//webpack.config.dev.js(只展現不一樣的地方) //.... //新增通用配置文件 const config = require('./config') //.... output: { path: path.resolve(__dirname, '../dist'), publicPath: config.publicPath,//就是修改了輸出的公網路徑爲配置文件中的路徑 filename: '[name].js' }, plugins: [ new webpack.HotModuleReplacementPlugin(), //刪除html模板(後面會解釋) //new htmlPlugin({ // template:'index.html' // }), ] //....
接下來修改webpack.config.js爲生產環境配置(一樣只列出不一樣的地方)
//webpack.config.js const config = require('./config') //刪除熱加載 //const hotMiddlewareScript = 'webpack-hot-middleware/client?reload=true' //新增文件清除插件 const cleanWebpackPlugin = require('clean-webpack-plugin') //.... entry: { main:path.resolve(__dirname, '../src/main.js')//取消熱加載 }, output: { path: path.resolve(__dirname, '../dist'), publicPath: config.publicPath, filename: '[name].js' }, //.... resolve: { alias: { 'vue$': 'vue/dist/vue.min.js'//生產使用壓縮的vue文件 }, extensions: ['*', '.js', '.vue', '.json'] }, plugins: [ //刪除熱加載 //new webpack.HotModuleReplacementPlugin(), //刪除html模板(後面會解釋) //new htmlPlugin({ // template:'index.html' // }), //增長dist刪除選項 new cleanWebpackPlugin(['dist'], { "root": path.resolve(__dirname, '../'), }) ] //....
最後修改server文件,以爲長能夠試着分紅開發生產兩個文件
//server.js const webpack = require('webpack') const webpackConfig = require('./build/webpack.config') const webpackDevConfig = require('./build/webpack.config.dev') const webpackDevMiddleware = require('webpack-dev-middleware') const webpackHotMiddleware = require('webpack-hot-middleware') const express = require('express') const path = require('path') //新增config和swig插件 const config = require('./build/config') const swig = require('swig') const app = express() //swig一款js模板引擎,是服務端向客戶端返回html的一種方式,swig只是衆多引擎中的一種; //這裏經過node向頁面返回html,而不是直接訪問dist中的index.html,因此到這裏已經把webpack中的html模板刪掉了; //若是使用webpack使用html插件,在切換生產和開發須要手動修改html的script; app.engine('html', swig.renderFile); app.set('view engine', 'html'); app.set('views', path.resolve(__dirname, './')); app.get('/', function(req, res) { res.type('text/html'); res.render('index'); }); if (config.isdev) { console.log('server運行在開發環境') const compiler = webpack(webpackDevConfig) app.use(webpackDevMiddleware(compiler, { // public path should be the same with webpack config publicPath: 'http://localhost:3000/', stats: { colors: true } })) app.use(webpackHotMiddleware(compiler)) } else { console.log('server運行在生產環境') webpack(webpackConfig, function(err, stats) { if (err) throw err //輸出打包信息(這裏又能夠用了) process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n\n') app.use(express.static(path.resolve(__dirname, './dist'))) }) } app.listen(config.port, function() { console.log('App is now running on port 3000!'); })
運行以前先裝下swig插件,同時修改下index.html,手寫
//index.html <script type="text/javascript" src="main.js"></script>
到目前爲止的目錄結構:
環境搭建完成了,業務代碼及後端邏輯下篇再講;
《手動搭建vue+node單頁面(二)》
https://segmentfault.com/a/11...