首页 > 前端技术 > Vue多页面依赖webpack开发共用配置
2017
02-22

Vue多页面依赖webpack开发共用配置

由于项目历史遗留问题,项目目录不尽合理。如下
root //其它文件
|–vue_dev // 基于vue开发的
……..|—package.json // 不解释
……..|—node_modules // 不演示
……..|—build // 打包运行代码
……..|—views // 下面会有很多项目
……..|—utils // 放一些公共的有用的东西
|–web //输出文件

根据项目目录,在view 下新建shaoxia_demo文件夹。其中包含 index.html ,index.js 分别如下。
index.html

<!DOCTYPE html> <html lang="zh"> <head> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <title>首页</title> </head> <body> <!-- vue的组件以自定义标签的形式使用 --> <favlist></favlist> </body> </html>

index.js

/** * Created by keli on 2016/6/8. */ import Vue from 'Vue' import Favlist from './components/Favlist' new Vue({ el: 'body', components: { Favlist } })

在components目录下新建一个 Favlist.vue 文件,作为我们的第一个组件:

<template> <div v-for="n in 4">{{msg}}</div> </template> <script> export default { data () { return { msg: 'Hello World!' } } } </script> <style> html{ background: #def; } </style>

我希望打包相关的代码跟实用代码分开。所以在 vue_dev下新建了一个build文件夹(先不要着急目录结构是否合理,后续步骤会说服你这是合理的)。build文件夹下新建webpack.config.js。如下:

/** * Created by keli on 2016/6/8. */ // nodejs 中的path模块 var path = require('path'); module.exports = { // 入口文件,path.resolve()方法,可以结合我们给定的两个参数最后生成绝对路径,最终指向的就是我们的index.js文件 entry: path.resolve(__dirname, '../views/shaoxia_demo/index.js'), // 输出配置 output: { // 输出路径是 myProject/output/static path: path.resolve(__dirname, '../../web/shaoxia_demo'), publicPath: 'static/', filename: '[name].[hash].js', chunkFilename: '[id].[chunkhash].js' }, module: { loaders: [ // 使用vue-loader 加载 .vue 结尾的文件 { test: /\.vue$/, loader: 'vue' } ] } }

在build目录下。执行:

webpack --display-modules --display-chunks

sorry,不出意外的话,会报错,它说没有发现 ‘./components/Favlist’ 模块,而我们明明有 ./components/Favlist.vue 文件,为什么它没发现呢?其实是这样的,当webpack试图去加载模块的时候,它默认是查找以 .js 结尾的文件的,它并不知道 .vue 结尾的文件是什么鬼玩意儿,所以我们要在配置文件中告诉webpack,遇到 .vue 结尾的也要去加载(就算不报错,最好也加上),添加 resolve 配置项,如下:

/** * Created by keli on 2016/6/8. */ // nodejs 中的path模块 var path = require('path'); module.exports = { // 入口文件,path.resolve()方法,可以结合我们给定的两个参数最后生成绝对路径,最终指向的就是我们的index.js文件 entry: path.resolve(__dirname, '../views/shaoxia_demo/index.js'), // 输出配置 output: { // 输出路径是 myProject/output/static path: path.resolve(__dirname, '../../web/shaoxia_demo'), publicPath: 'static/', filename: '[name].[hash].js', chunkFilename: '[id].[chunkhash].js' }, resolve: { extensions: ['', '.js', '.vue'] }, module: { loaders: [ // 使用vue-loader 加载 .vue 结尾的文件 { test: /\.vue$/, loader: 'vue' } ] } }

这样,当我们去加载 ‘./components/Favlist’ 这样的模块时,webpack首先会查找 ./components/Favlist.js 如果没有发现Favlist.js文件就会继续查找 Favlist.vue 文件,现在再次运行构建命令,我们成功了,这时我们会在我们的输出目录中看到一个js文件:
之所以会这样输出,是因为我们的 webpack.config.js 文件中的输出配置中指定了相应的输出信息,这个时候,我们修改 index.html ,将输出的js文件引入:

<!DOCTYPE html> <html lang="zh"> <head> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no"> <meta charset="utf-8"> <title>首页</title> </head> <body> <!-- vue的组件以自定义标签的形式使用 --> <favlist></favlist> <script src="../../../web/shaoxia_demo/main.900ea8a3f270c8f19b6c.js"></script> </body> </html>

不出意外的话,页面空白,控制台会报错Uncaught SyntaxError: Unexpected token import。是因为我们用了es6语法,但没有把它转成浏览器认识的。所以,继续在webpack.config.js中加loader。这次添加的是babel-loader。

/** * Created by keli on 2016/6/8. */ // nodejs 中的path模块 var path = require('path'); module.exports = { // 入口文件,path.resolve()方法,可以结合我们给定的两个参数最后生成绝对路径,最终指向的就是我们的index.js文件 entry: path.resolve(__dirname, '../views/shaoxia_demo/index.js'), // 输出配置 output: { // 输出路径是 myProject/output/static path: path.resolve(__dirname, '../../web/shaoxia_demo'), publicPath: 'static/', filename: '[name].[hash].js', chunkFilename: '[id].[chunkhash].js' }, resolve: { extensions: ['', '.js', '.vue'] }, module: { loaders: [ // 使用vue-loader 加载 .vue 结尾的文件 { test: /\.vue$/, loader: 'vue' }, { test:/\.js$/, loader: 'babel?presets=es2015', exclude: /node_modules/ } ] } }

再次编译,打开这个html文件,可以正确看到页面了。

那么问题来了,难道我们每次都要手动的引入输出的js文件吗?因为每次构建输出的js文件都带有 hash 值,如 main.900ea8a3f270c8f19b6c.js,就不能更智能一点吗?每次都自动写入?怎么会不可能,否则这东西还能火吗,要实现这个功能,我们就要使用webpack的插件了,html-webpack-plugin插件,这个插件可以创建html文件,并自动将依赖写入html文件中。
首先在vue_dev中安装 html-webpack-plugin 插件:

npm install html-webpack-plugin --save-dev

然后再修改配置项,添加这个插件,让它发挥作用:

/** * Created by keli on 2016/6/8. */ // nodejs 中的path模块 var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { // 入口文件,path.resolve()方法,可以结合我们给定的两个参数最后生成绝对路径,最终指向的就是我们的index.js文件 entry: path.resolve(__dirname, '../views/shaoxia_demo/index.js'), // 输出配置 output: { // 输出路径是 myProject/output/static path: path.resolve(__dirname, '../../web/shaoxia_demo'), publicPath: 'static/', filename: '[name].[hash].js', chunkFilename: '[id].[chunkhash].js' }, resolve: { extensions: ['', '.js', '.vue'] }, module: { loaders: [ // 使用vue-loader 加载 .vue 结尾的文件 { test: /\.vue$/, loader: 'vue' }, { test:/\.js$/, loader: 'babel?presets=es2015', exclude: /node_modules/ } ] }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', //相对于output.path,产出路径。 template: path.resolve(__dirname, '../views/shaoxia_demo/index.html'), //html模板,绝对路径。 inject: true }) ] }

然后再次执行构建命令,成功之后,看你的输出目录,多出来一个index.html文件,双击它,代码正确执行,你可以打开这个文件查看一下,webpack自动帮我们引入了相应的文件。

问题继续来了,难道每次我们都要构建之后才能查看运行的代码吗?那岂不是很没有效率,别担心,webpack提供了几种方式,进行热加载,在开发模式中,我们使用这种方式来提高效率,这里要介绍的,是使用 webpack-dev-middleware中间件和webpack-hot-middleware中间件,首先在vue_dev中安装两个中间件:

npm install webpack-dev-middleware webpack-hot-middleware --save-dev 

另外,还要安装express,这是一个nodejs框架

npm install express --save-dev 

在开始之前,我先简单介绍一下这两个中间件,之所以叫做中间件,是因为nodejs的一个叫做express的框架中有中间件的概念,而这两个包要作为express中间件使用,所以称它们为中间件,那么他们能干什么呢?
1.webpack-dev-middleware
我们之前所面临的问题是,如果我们的代码改动了,我们要想看到浏览器的变化,需要先对项目进行构建,然后才能查看效果,这样对于开发效率来讲,简直就是不可忍受的一件事,试想我仅仅修改一个背景颜色就要构建一下项目,这尼玛坑爹啊,好在有webpack-dev-middleware中间件,它是对webpack一个简单的包装,它可以通过连接服务器服务那些从webpack发射出来的文件,它有一下几点好处:
1、不会向硬盘写文件,而是在内存中,注意我们构建项目实际就是向硬盘写文件。
2、当文件改变的时候,这个中间件不会再服务旧的包,你可以直接帅新浏览器就能看到最新的效果,这样你就不必等待构建的时间,所见即所得。
下面我们在build目录中创建一个 dev-server.js 的文件,并写入一下内容:

/** * Created by keli on 2016/6/8. */ // 引入必要的模块 var express = require('express') var webpack = require('webpack') var config = require('./webpack.config') // 创建一个express实例 var app = express() // 调用webpack并把配置传递过去 var compiler = webpack(config) // 使用 webpack-dev-middleware 中间件 var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: config.output.publicPath, stats: { colors: true, chunks: false } }) // 注册中间件 app.use(devMiddleware) // 监听 8888端口,开启服务器 app.listen(8888, function (err) { if (err) { console.log(err) return } console.log('Listening at http://localhost:8888') })

此时,我们在vue_dev运行下面的命令,开启服务:

node build/dev-server.js

如果控制台没有报错,那就说明服务启动成功。
接下来打开浏览器,输入:

http://localhost:8888/views/shaoxia_demo/index.html

如果不出意外的话,会报404。
我们要对我们的 webpack.config.js 配置文件做两处修改:
1 将publicPath改为’/’

output: { // 输出路径相对于vue_dev是 ../web/shaoxia_demo path: path.resolve(__dirname, '../../web/shaoxia_demo'), publicPath: '/', filename: '[name].[hash].js', chunkFilename: '[id].[chunkhash].js' },

2.将 plugins 中 HtmlWebpackPlugin 中的 filename 修改为 ‘views/shaoxia_demo/index.html’

plugins: [ new HtmlWebpackPlugin({ filename: 'views/shaoxia_demo/index.html', template: path.resolve(__dirname, '../views/shaoxia_demo/index.html'), //html模板,绝对路径。 inject: true }) ] 

重启服务,刷新页面,OK了。
是这样开发模式下的确是成功了,可是我们直接修改了 webpack.config.js 文件,这就意味着当我们执行 构建命令 的时候,配置变了,那么我们的构建也跟着变了,所以,一个好的方式是,不去修改webpack.config.js文件,我们在build目录下新建一个 webpack.dev.conf.js文件,意思是开发模式下要读取的配置文件,并写入一下内容:

var HtmlWebpackPlugin = require('html-webpack-plugin') var path = require('path'); // 引入基本配置 var config = require('./webpack.config'); config.output.publicPath = '/'; config.plugins = [ new HtmlWebpackPlugin({ filename: 'views/shaoxia_demo/index.html', template: path.resolve(__dirname, '../views/shaoxia_demo/index.html'), //html模板,绝对路径。 inject: true }) ]; module.exports = config;

这样,我们在dev环境下的配置文件中覆盖了基本配置文件,我们只需要在dev-server.js中将

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

修改为:

var config = require('./webpack.dev.conf') 

即可,然后,重启服务,刷新浏览器,你应该得到同样的成功结果,而这一次当我们执行构建命令:

webpack --display-modules --display-chunks --config build/webpack.config.js 

并不会影响构建输出,因为我们没有直接修改webpack.config.js文件。

现在我们已经使用 webpack-dev-middleware 搭建基本的开发环境了,

但是

我们并不满足,因为我们每次都要手动去刷新浏览器,所谓的热加载,意思就是说能够追踪我们代码的变化,并自动更新界面,甚至还能保留程序状态。要完成热加载,我们就需要使用另外一个中间件 webpack-hot-middleware

2.webpack-hot-middleware

webpack-hot-middleware 只配合 webpack-dev-middleware 使用,它能给你提供热加载。
它的使用很简单,总共分4步:
第1步、安装,我们上面已经安装过了
第2步、在 webpack.dev.conf.js 配置文件中添加三个插件,如下:

var webpack = require('webpack'); // 添加三个插件 new webpack.optimize.OccurenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin(),

第3步、在 webpack.config.js 文件中入口配置中添加 ‘webpack-hot-middleware/client’,如下:

 entry: ['webpack-hot-middleware/client',path.resolve(__dirname, '../views/shaoxia_demo/index.js')],

第4步、在 dev-server.js 文件中使用插件

/** * Created by keli on 2016/6/8. */ // 引入必要的模块 var express = require('express') var webpack = require('webpack') var config = require('./webpack.dev.conf') // 创建一个express实例 var app = express() // 调用webpack并把配置传递过去 var compiler = webpack(config) // 使用 webpack-dev-middleware 中间件 var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: config.output.publicPath, stats: { colors: true, chunks: false } }) // 使用 webpack-hot-middleware 中间件 var hotMiddleware = require('webpack-hot-middleware')(compiler) // 注册中间件 app.use(devMiddleware) // 注册中间件 app.use(hotMiddleware) // 监听 8888端口,开启服务器 app.listen(8888, function (err) { if (err) { console.log(err) return } console.log('Listening at http://localhost:8888') })

ok,现在重启的服务,然后修改 Favlist.vue 中的页面背景颜色为 ‘#000’.然后查看你的浏览器,是不是你还没有刷新就已经得带改变了?如果没有,重启几次或者去倒杯水喝就好了。

那么这样就完美了吗?还没有,如果你细心,你会注意到,我们上面在第2步中修改了 webpack.config.js 这个基本配置文件,修改了入口配置,如下:

 entry: ['webpack-hot-middleware/client',path.resolve(__dirname, '../views/shaoxia_demo/index.js')],

这也会导致我们之前讨论过的问题,就是会影响构建,所以我们不要直接修改 webpack.config.js 文件,我们还是在 webpack.dev.conf.js 文件中配置,如下:

// 动态向入口配置中注入 webpack-hot-middleware/client var devClient = 'webpack-hot-middleware/client'; Object.keys(config.entry).forEach(function (name, i) { var extras = [devClient] config.entry[name] = extras.concat(config.entry[name]) }) 

但是我们还是要讲 webpack.config.js 文件中的入口配置修改为多入口配置的方式,这个修改不会影响构建,所以无所谓:

entry:{ index:path.resolve(__dirname, '../views/shaoxia_demo/index.js') },

重启你的服务,刷新一下浏览器,然后修改 Favlist.vue 中的背景色.再次查看浏览器,发现可以热加载。但是这样就结束了吗?还没有,不信你修改 index.html 文件,看看会不会热加载,实际上不会,你还是需要手动刷新页面,为了能够当 index.html 文件的改动也能够触发自动刷新,我们还需要做一些工作。

第一步:在 dev-server.js 文件中监听html文件改变事件,修改后的 dev-server.js 文件如下:

/** * Created by keli on 2016/6/8. */ // 引入必要的模块 var express = require('express') var webpack = require('webpack') var config = require('./webpack.dev.conf') // 创建一个express实例 var app = express() // 调用webpack并把配置传递过去 var compiler = webpack(config) // 使用 webpack-dev-middleware 中间件 var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: config.output.publicPath, stats: { colors: true, chunks: false } }) // 使用 webpack-hot-middleware 中间件 var hotMiddleware = require('webpack-hot-middleware')(compiler) // webpack插件,监听html文件改变事件 compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { // 发布事件 hotMiddleware.publish({ action: 'reload' }) cb() }) }) // 注册中间件 app.use(devMiddleware) // 注册中间件 app.use(hotMiddleware) // 监听 8888端口,开启服务器 app.listen(8888, function (err) { if (err) { console.log(err) return } console.log('Listening at http://localhost:8888') })

从上面的代码中可以看到,我们增加了如下代码:

// webpack插件,监听html文件改变事件 compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { // 发布事件 hotMiddleware.publish({ action: 'reload' }) cb() }) })

这段代码可能你看不懂,因为这涉及到webpack插件的编写,读者可以参阅下面的连接:

webpack 插件doc1

webpack 插件doc2

我们可以看到,html-webpack-plugin 这个插件的确提供了几个可选的事件,下面也提供了使用方法,这样,我们就能够监听到html文件的变化,然后我们使用下面的代码发布一个事件:

hotMiddleware.publish({ action: 'reload' }) 

第二步:修改 webpack.dev.conf.js 文件如下:

var HtmlWebpackPlugin = require('html-webpack-plugin') var path = require('path'); var webpack = require('webpack'); // 引入基本配置 var config = require('./webpack.config'); config.output.publicPath = '/'; config.plugins = [ // 添加三个插件 new webpack.optimize.OccurenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin(), new HtmlWebpackPlugin({ filename: 'views/shaoxia_demo/index.html', template: path.resolve(__dirname, '../views/shaoxia_demo/index.html'), //html模板,绝对路径。 inject: true }) ]; // 动态向入口配置中注入 webpack-hot-middleware/client var devClient = './build/dev-client'; Object.keys(config.entry).forEach(function (name, i) { var extras = [devClient] config.entry[name] = extras.concat(config.entry[name]) }) module.exports = config; 

我们修改了devClient变量,将 ‘webpack-hot-middleware/client’ 替换成 ‘./build/dev-client’,最终会导致,我们入口配置会变成下面这样:

entry: { index: [ './build/dev-client', path.resolve(__dirname, '../views/shaoxia_demo/index.js') ] },

第三步:新建 build/dev-client.js 文件,并编辑如下内容:

/** * Created by keli on 2016/6/8. */ var hotClient = require('webpack-hot-middleware/client') // 订阅事件,当 event.action === 'reload' 时执行页面刷新 hotClient.subscribe(function (event) { if (event.action === 'reload') { window.location.reload() } }) 

这里我们除了引入 ‘webpack-hot-middleware/client’ 之外订阅了一个事件,当 event.action === ‘reload’ 时触发,还记得我们在 dev-server.js 中发布的事件吗:

hotMiddleware.publish({ action: 'reload' })

这样,当我们的html文件改变后,就可以监听的到,最终会执行页面刷新,而不需要我们手动刷新,现在重启服务,去尝试能否对html文件热加载吧。答案是yes。

好了,开发环境终于搞定了,下面我们再来谈一谈生产环境,也就是构建输出,我们现在可以执行一下构建命令,看看输出的内容是什么,为了不必每次都要输入下面这条长命令。

webpack --display-modules --display-chunks --config build/webpack.config.js 

我在 shaoxia_demo中新建了一个package.json文件,把命令放要script中。但新建package.json文件的原因并不止是这些。因为还会有其它信息放在这个文件中。例如这次活动项目作者,描述,依赖包,bug提交作途径等。具体请查 node package.json相关介绍。
如下:

{ "name": "shaoxia_demo", "author":"licat", "version": "0.0.1", "scripts": { "dev":"node ../../build/dev-server.js", "build": "webpack --display-modules --display-chunks --config ../../build/webpack.config.js" } } 

这样,我们就可以通过执行下面命令来进行构建,同时我们还增加了一条开启开发服务器的命令:

// 构建 npm run build // 开启开发服务器 npm run dev 

回过头来,我们执行构建命令: npm run build,查看输出内容。
现在我们只有一个js文件输出了,并没有css文件输出,在生产环境,我们希望css文件生成单独的文件,所以我们要使用 extract-text-webpack-plugin 插件,安装:

npm install extract-text-webpack-plugin --save-dev 

然后在build目录下新建 webpack.prod.conf.js 文件,顾名思义,这个使我们区别于开发环境,用于生产环境的配置文件,并编辑一下内容:

var HtmlWebpackPlugin = require('html-webpack-plugin') var ExtractTextPlugin = require('extract-text-webpack-plugin') var path = require('path'); var webpack = require('webpack'); // 引入基本配置 var config = require('./webpack.config'); config.vue = { loaders: { css: ExtractTextPlugin.extract("css") } }; config.plugins = [ // 提取css为单文件 new ExtractTextPlugin("[name].[contenthash].css"), new HtmlWebpackPlugin({ filename: 'index.html', template: path.resolve(__dirname, '../views/shaoxia_demo/index.html'), //html模板,绝对路径。 inject: true }) ]; module.exports = config;

上面的代码中,我们覆盖了 webpack.config.js 配置文件的 config.plugins 项。
然后修改 package.json 文件中的 script 项为如下:

"scripts": { "build": "webpack --display-modules --display-chunks --config ../../build/webpack.prod.conf.js", "dev": "node ../../build/dev-server.js" },

我们使用 webpack.prod.conf.js 为配置去构建,接下来执行:

npm run build 

查看你的输出内容,如下图,css文件未提取出来了。
另外我们还可以添加如下插件在我们的 webpack.prod.conf.js 文件中,作为生产环境使用。

new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }), // 压缩代码 new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), new webpack.optimize.OccurenceOrderPlugin(),

大家可以搜索这些插件,了解他的作用,这篇文章要介绍的太多,所以我不一一讲解了。

但是

在我们的views下面会有很多个项目。而我们build中的配置路径都是写死的。所以有这样一个需求:
在views中我们新建了项目,随之新建了package.json。我们在package.json的script中定义一个命令。每次执行 npm run 即可进入开发模式,执行 npm run build即可完成打包。

所以

我们需要把build中有关文件路径的都提出来,可以通过命令行输入。为了达到这个目的,我们引入了一个commander 插件,它可以非常方便地从命令行解析参数。

经过改造后有变动的文件如下:
新加的 build/build.js

var webpack= require("webpack"); var program = require('commander'); program .version('0.0.1') .option('-e, --entry <n> ', '添加入口') .option('-op, --outpath <n> ', '输入文件路径') .option('-h, --htmltemplate <n> ', 'html模板路径') .parse(process.argv); var config = require('./webpack.prod.conf')(program); var compiler = webpack(config); compiler.run(function(err,stats){ if (err){ console.log(err); return } })

build/dev-server.js

/** * Created by keli on 2016/6/8. */ // 引入必要的模块 var express = require('express') var webpack = require('webpack') var program = require('commander'); program .version('0.0.1') .option('-e, --entry <n> ', '添加入口') .option('-op, --outpath <n> ', '输入文件路径') .option('-h, --htmltemplate <n> ', 'html模板路径') .parse(process.argv); var config = require('./webpack.dev.conf')(program); // 创建一个express实例 var app = express() // 调用webpack并把配置传递过去 var compiler = webpack(config) // 使用 webpack-dev-middleware 中间件 var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: config.output.publicPath, stats: { colors: true, chunks: false } }) // 使用 webpack-hot-middleware 中间件 var hotMiddleware = require('webpack-hot-middleware')(compiler) // webpack插件,监听html文件改变事件 compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { // 发布事件 hotMiddleware.publish({ action: 'reload' }) cb() }) }) // 注册中间件 app.use(devMiddleware) // 注册中间件 app.use(hotMiddleware) // 监听 8888端口,开启服务器 app.listen(8888, function (err) { if (err) { console.log(err) return } console.log('Listening at http://localhost:8888') })

build/webpack.config.js

/** * Created by keli on 2016/6/8. */ // nodejs 中的path模块 var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = function(program){ var config = { // 入口文件,path.resolve()方法,可以结合我们给定的两个参数最后生成绝对路径,最终指向的就是我们的index.js文件 entry:{ index:path.resolve(__dirname, '../views/',program.entry) }, // 输出配置 output: { path: path.resolve(__dirname, '../../web/',program.outpath), publicPath: '/', filename: '[name].[hash].js', chunkFilename: '[id].[chunkhash].js' }, resolve: { extensions: ['', '.js', '.vue'] }, module: { loaders: [ // 使用vue-loader 加载 .vue 结尾的文件 { test: /\.vue$/, loader: 'vue' }, { test:/\.js$/, loader: 'babel?presets=es2015', exclude: /node_modules/ } ] }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: path.resolve(__dirname, '../views/,',program.htmltemplate), //html模板,绝对路径。 inject: true }) ] } return config; } 

build/webpack.dev.conf.js

var HtmlWebpackPlugin = require('html-webpack-plugin') var path = require('path'); var webpack = require('webpack'); module.exports = function(program){ // 引入基本配置 var config = require('./webpack.config')(program); config.output.publicPath = '/'; config.plugins = [ // 添加三个插件 new webpack.optimize.OccurenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin(), new HtmlWebpackPlugin({ filename: 'views/'+program.htmltemplate, template: path.resolve(__dirname, '../views/'+program.htmltemplate), //html模板,绝对路径。 inject: true }) ]; // 动态向入口配置中注入 webpack-hot-middleware/client var devClient = '../../build/dev-client'; Object.keys(config.entry).forEach(function (name, i) { var extras = [devClient] config.entry[name] = extras.concat(config.entry[name]) }) return config };

build/webpack.prod.conf.js

var HtmlWebpackPlugin = require('html-webpack-plugin') var ExtractTextPlugin = require('extract-text-webpack-plugin') var path = require('path'); var webpack = require('webpack'); function rtn(program){ // 引入基本配置 var config = require('./webpack.config')(program); config.vue = { loaders: { css: ExtractTextPlugin.extract("css") } }; config.plugins = [ // 提取css为单文件 new ExtractTextPlugin("[name].[contenthash].css"), new HtmlWebpackPlugin({ filename: 'index.html', template: path.resolve(__dirname, '../views/',program.htmltemplate), //html模板,绝对路径。 inject: true }) ]; return config; } module.exports = rtn;

现在,在views下新建一个项目yaha,我们来试验一下build是否可靠。yaha下面包含

1.index.html :入口模板

2.index.js :入口文件

3.package.json :项目信息

其中 package.json 中 的scripts如下


"scripts": {
"build": "node ../../build/build.js -e yaha/index.js --outpath yaha -h yaha/index.html",
"dev": "node ../../build/dev-server.js -e yaha/index.js --outpath yaha -h yaha/index.html"
}

执行 npm run dev 我们发现可以愉快地进入 开发模式了, 执行npm run build 也打包出我们想要的文件了。而我们无需编写webpack.config文件。只需要在package.json换掉一些参数。

参考资料:
HcySunYang
webpack官网

作者:keliyxyz 发表于2016/6/8 19:01:57 原文链接
最后编辑:
作者:管理员
这个作者貌似有点懒,什么都没有留下。