2016-11-28 23 views
4

我是webpack的新手,所以這可能是我的一個愚蠢的錯誤。用vuejs項目正確配置webpack-dev-middleware

這是我的項目設置(根,至少相關部分):

+-- public 
| | 
| +-- index.html 
|  
+-- src 
| | 
| +-- App.vue 
| +-- main.js 
| +-- assets 
|  
+-- package.json 
|  
+-- webpack.config.js 

現在我想使用的WebPack-DEV(熱)-middleware爲我的index.html,然後創建一個從我的src文件夾捆綁在內存中。現在,我可以得到中間件設置(通過NPM頁),我看到了束被創建(通過日誌記錄在控制檯),但兩件事情是我不明白:

  • 如何index.html的服務
  • 如何使用在內存中創建的包?

有人能解釋一下這個中間件的工作原理嗎?這是我的WebPack配置文件(這是插入中間件需要的,它只是一個是被通過VUE-CLI創建的WebPack配置文件的複印件):

var path = require('path') 
var webpack = require('webpack') 

module.exports = { 
    entry: './src/main.js', 
    output: { 
    path: path.resolve(__dirname, './dist'), 
    publicPath: '/dist/', 
    filename: 'build.js' 
    }, 
    module: { 
    rules: [ 
     { 
     test: /\.vue$/, 
     loader: 'vue-loader', 
     options: { 
      // vue-loader options go here 
     } 
     }, 
     { 
     test: /\.js$/, 
     loader: 'babel-loader', 
     exclude: /node_modules/ 
     }, 
     { 
     test: /\.(png|jpg|gif|svg)$/, 
     loader: 'file-loader', 
     options: { 
      name: '[name].[ext]?[hash]' 
     } 
     } 
    ] 
    }, 
    resolve: { 
    alias: { 
     'vue$': 'vue/dist/vue.common.js' 
    } 
    }, 
    devServer: { 
    historyApiFallback: true, 
    noInfo: true 
    }, 
    devtool: '#eval-source-map' 
} 

if (process.env.NODE_ENV === 'production') { 
    module.exports.devtool = '#source-map' 
    // http://vue-loader.vuejs.org/en/workflow/production.html 
    module.exports.plugins = (module.exports.plugins || []).concat([ 
    new webpack.DefinePlugin({ 
     'process.env': { 
     NODE_ENV: '"production"' 
     } 
    }), 
    new webpack.optimize.UglifyJsPlugin({ 
     sourceMap: true, 
     compress: { 
     warnings: false 
     } 
    }), 
    new webpack.LoaderOptionsPlugin({ 
     minimize: true 
    }) 
    ]) 
} 

我知道這可能是不正確的配置,有人可能會指出一些事情嗎?

在此先感謝您的幫助!

編輯(此安裝工程)

我現在server.js:

var express = require('express'); 
var logger = require('morgan'); 
var bodyParser = require('body-parser'); 
var exphbs = require('express-handlebars'); 
var helmet = require('helmet'); 
var redis = require('redis'); 
var redisAdapter = require('socket.io-redis'); 
var app = express(); 
var server = require('http').Server(app); 
var io = require('socket.io')(server); 
// use the redis adapter to create sticky sessions, this is needed because of the different clusters 
io.adapter(redisAdapter(require('./app/lib/config').credentials.redis.url)); 

//setup security =============================================================== 
require('./app/lib/security-setup')(app, helmet); 

// configuration =============================================================== 
app.use(logger('dev')); // log every request to the console 

// set up our express application ============================================== 

// Make the body object available on the request 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: true })); 

//set handlebars as default templating engine 
app.engine('handlebars', exphbs()); 
app.set('view engine', 'handlebars'); 

// serve the static content ==================================================== 
if (app.settings.env === 'development') { 
    var webpackConfig = require('./webpack.config.js') 
    var compiler = require('webpack')(webpackConfig) 
    var devMiddleware = require('webpack-dev-middleware')(compiler, { 
    publicPath: webpackConfig.output.publicPath, 
    }) 
    var hotMiddleware = require('webpack-hot-middleware')(compiler) 

    app.use(devMiddleware) 
    app.use(hotMiddleware) 
} else { 
    app.use(express.static(__dirname + '/public')); 
} 

// set up global variables ===================================================== 
app.use(function(req, res, next) { 
    //set the io object on the response, so we can access it in our routes 
    res.io = io; 
    next(); 
}); 

// routes ====================================================================== 
require('./app/routes.js')(app); // load our routes and pass in our app 

// export so bin/www can launch ================================================ 
module.exports = {app: app, server: server}; 

我./bin/www:

#!/usr/bin/env node 

/** 
* Module dependencies. 
*/ 

var app = require('../server').app; 
var cluster = require('cluster'); 
var debug = require('debug')('temp:server'); 
var http = require('http'); 
var numCPUs = process.env.WORKERS || require('os').cpus().length; 

/** 
* Get port from environment and store in Express. 
*/ 

var port = normalizePort(process.env.PORT || '3000'); 
app.set('port', port); 

if (cluster.isMaster) { 
    // Fork workers. 
    for (var i = 0; i < numCPUs; i++) { 
    cluster.fork(); 
    } 

    // If a worker dies, log it to the console and start another worker. 
    cluster.on('exit', function(worker, code, signal) { 
    console.log('Worker ' + worker.process.pid + ' died.'); 
    cluster.fork(); 
    }); 

    // Log when a worker starts listening 
    cluster.on('listening', function(worker, address) { 
    console.log('Worker started with PID ' + worker.process.pid + '.'); 
    }); 

} else { 
    /** 
    * Create HTTP server. 
    */ 

    var server = require('../server').server; 

    /** 
    * Listen on provided port, on all network interfaces. 
    */ 
    server.listen(port); 

    server.on('error', onError); 
    server.on('listening', onListening); 
} 

// The rest of the bin/www file..... 

/** 
* Normalize a port into a number, string, or false. 
*/ 

function normalizePort(val) { 
    var port = parseInt(val, 10); 

    if (isNaN(port)) { 
    // named pipe 
    return val; 
    } 

    if (port >= 0) { 
    // port number 
    return port; 
    } 

    return false; 
} 

/** 
* Event listener for HTTP server "error" event. 
*/ 

function onError(error) { 
    if (error.syscall !== 'listen') { 
    throw error; 
    } 

    var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; 

    // handle specific listen errors with friendly messages 
    switch (error.code) { 
    case 'EACCES': 
     console.error(bind + ' requires elevated privileges'); 
     process.exit(1); 
     break; 
    case 'EADDRINUSE': 
     console.error(bind + ' is already in use'); 
     process.exit(1); 
     break; 
    default: 
     throw error; 
    } 
} 

/** 
* Event listener for HTTP server "listening" event. 
*/ 

function onListening() { 
    var addr = server.address(); 
    var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; 
    debug('Listening on ' + bind); 
} 

我的工作webpack.config。 js:

var path = require('path') 
var webpack = require('webpack') 
var HtmlWebpackPlugin = require('html-webpack-plugin') 

module.exports = { 
    entry: [ 
    'webpack/hot/dev-server', 
    'webpack-hot-middleware/client', 
    './src/main.js' 
    ], 
    output: { 
    path: path.resolve(__dirname, './dist'), 
    publicPath: '/dist/', 
    filename: 'build.js' 
    }, 
    module: { 
    rules: [ 
     { 
     test: /\.vue$/, 
     loader: 'vue-loader', 
     options: { 
      // vue-loader options go here 
     } 
     }, 
     { 
     test: /\.less$/, 
     loader: "style!css!less" 
     }, 
     { 
     test: /\.js$/, 
     loader: 'babel-loader', 
     exclude: /node_modules/ 
     }, 
     { 
     test: /\.(png|jpg|gif|svg)$/, 
     loader: 'file-loader', 
     options: { 
      name: '[name].[ext]?[hash]' 
     } 
     } 
    ] 
    }, 
    resolve: { 
    alias: { 
     'vue$': 'vue/dist/vue.common.js' 
    } 
    }, 
    devServer: { 
    historyApiFallback: true, 
    noInfo: true 
    }, 
    devtool: '#eval-source-map', 
    plugins: [ 
    new HtmlWebpackPlugin({ 
     filename: 'index.html', 
     template: path.resolve(__dirname, 'public/index.html'), 
     inject: true 
    }), 
    new webpack.optimize.OccurrenceOrderPlugin(), 
    new webpack.HotModuleReplacementPlugin(), 
    new webpack.NoErrorsPlugin() 
    ] 
} 

if (process.env.NODE_ENV === 'production') { 
    module.exports.devtool = '#source-map' 
    // http://vue-loader.vuejs.org/en/workflow/production.html 
    module.exports.plugins = (module.exports.plugins || []).concat([ 
    new webpack.DefinePlugin({ 
     'process.env': { 
     NODE_ENV: '"production"' 
     } 
    }), 
    new webpack.optimize.UglifyJsPlugin({ 
     sourceMap: true, 
     compress: { 
     warnings: false 
     } 
    }), 
    new webpack.LoaderOptionsPlugin({ 
     minimize: true 
    }) 
    ]) 
} 

回答

6

如何提供index.html

要提供index.html文件,您需要運行一個dev服務器。這聽起來像是你根據你在內存中創建你的包的記錄成功地做到了這一點。但是,我無法在您的設置中看到它的文件?我認爲另外一個文件名爲如下:dev-server.js,這將是你的切入點,以服務於你的應用程序,即npm run dev

的package.json

"scripts": { 
    "dev": "node dev-server.js", 
    ... 

在此的WebPack開發服務器一般會快遞,這是您傳遞給您的快遞服務器的配置,它將爲您的index.html服務。正如你想要熱重載,你會通過你的中間件層來傳遞你的webpack配置。

對於熱重裝你需要兩個主要的中間件:

  • 的WebPack-DEV-中間件
  • 的WebPack熱中間件

然後,你將需要你的配置傳遞給的WebPack並將您的webpack編譯器傳遞給中間件,即

dev-server.js

var app = require('express')() 

var webpackConfig = require('./webpack.config.js') 

var compiler = require('webpack')(webpackConfig) 

var devMiddleware = require('webpack-dev-middleware')(compiler, { 
    publicPath: webpackConfig.output.publicPath, 
}) 

var hotMiddleware = require('webpack-hot-middleware')(compiler) 

app.use(devMiddleware) 

app.use(hotMiddleware) 

現在關鍵文件將成爲您的WebPack的配置,如上面提到:./webpack.config.js

這將導致你的下一個問題:如何使用在內存中創建捆綁多數民衆贊成?

你在上面發佈的文件看起來是對與問候關鍵部位使用輸出內舉行的捆綁,您有:

webpack.config.js

output: { 
    path: path.resolve(__dirname, './dist'), 
    publicPath: '/dist/', 
    filename: 'build.js' 
}, 

您正在創建相對於當前工作目錄的軟件包dist/build.js。這主要是你需要您的index.html中指向該文件的任何引用,即<script src="/dist/build.js"></script>

你怎麼做到這一點可手動但是我們會經常補充進一步的WebPack插件內自動建立這個腳本標記您的(在這種情況下,內存再次)輸出HTML:

webpack.config.js

plugins: [ 
    // https://github.com/ampedandwired/html-webpack-plugin 
    new HtmlWebpackPlugin({ 
    filename: 'index.html', 
    template: path.resolve(__dirname, 'public/index.html'), 
    inject: true 
    }), 
    ... 

的HtmlWebpackPlugin現在你基本上是如何引用什麼輸出文件名爲:filename和關鍵它在哪裏存儲:template所以如果你想移動你的index.html文件,這是你告訴webpack在哪裏找到它的地方。 HtmlWebpackPlugin現在將輸出'index.html'放在前面引用的publicPath處,因此要訪問此文件,您可以將其稱爲/dist/index.html

最後你需要熱重裝一些進一步的插件,讓你的整個的WebPack plugins數組看起來像:

webpack.config.js

plugins: [ 
    new webpack.optimize.OccurenceOrderPlugin(), 
    new webpack.HotModuleReplacementPlugin(), 
    new webpack.NoErrorsPlugin(), 
    // https://github.com/ampedandwired/html-webpack-plugin 
    new HtmlWebpackPlugin({ 
    filename: 'index.html', 
    template: 'bar/index.html', 
    inject: true 
    }) 
] 

現在我們回到dev亡server.js文件 - 或任何您稱爲您正在配置的快速內容 - 並啓動配置的快速服務器:

dev-server。JS

module.exports = app.listen(8080, function (err) { 
    if (err) { 
    console.log(err) 
    return 
    } 
}) 

因此,與上述的配置你會打開以下網址:localhost:8080/dist/index.html

+0

+1了這個答案,它只是心不是顯示,因爲我的分數低了。謝謝,真的幫助我理解!我現在在localhost:3000/dist/index.html中獲得一個404。這可能是因爲我在使用羣集嗎?我用最新的server.js,webpack config和./bin/www更新了我的問題。 –

+0

不用擔心,如果有幫助,你可以標記爲答案。我會在一秒鐘內看看你的server.js - 看看有沒有什麼突出的 – GuyC

+0

看着配置我從來沒有使用集羣,所以我不知道如果這是造成問題。如果你添加上面的最終開發服務器配置,它會工作嗎:'app.listen(...',而不是使用你的'。/ bin/www'配置? – GuyC