项目使用webpack怎么打包项目打包,怎么样引入JTopo的官方API?急~~~

基于&webpack&-reactjs搭建前端项目工程_h5house_新浪博客
基于&webpack&-reactjs搭建前端项目工程
1. 技术选型
最近在一个项目初步尝试使用了reactJS,开发周期两周,选用的技术栈大致如下:
JavaScript:
Language: ES6
Framework: React, Redux
​Language: SCSS
Framework: ant-design
Build Tool:
Dependency manage
Git workflow:
Gitlab flow
1、全局安装webpack
$ npm install -g
2、作为项目依赖安装
$ npm install webpack --save-dev
3、webpack 的配置项主要包括以下几点:
1)entry: 入口,定义要打包的文件
2)output: 出口,定义打包输出的文件;包括路径,文件名,还可能有运行时的访问路径(publicPath)参数
3)module:
webpack将所有的资源都看做是模块,而模块就需要加载器;主要定义一些loaders,定义哪些后缀名的文件应该用哪些loader
test: 检测哪些文件需要此loader,是一个正则表达式
exclude: 忽略哪些文件
4)resolve: 定义能够被打包的文件,文件后缀名
5)plugins: 定义一些额外的插件
处理样式:sass-loader、style-loader、css-loader,将 sass 转成 css
图片处理,url-loader、file-loader、image-webpack-loader, 将图片转换成base64
或者 进行压缩
babel-loader,babel-preset-es2015,babel-preset-react,将es6或更高级的代码转成es5的代码
代码热替换:HotModuleReplacementPlugin
生成html文件:HtmlWebpackPlugin​
报错但不退出webpack进程:NoErrorsPlugin​
代码压缩:UglifyJsPlugin​​
自动打开浏览器:
OpenBrowserPlugin​
设置环境变量:
DefinePlugin​
2.3 使用 webpack-dev-server 启动服务器
在项目目录下输入命令
$ webpack-dev-servere
2.3.1 刷新功能
webpack提供的一个静态资源服务器,这个家伙可不太好配置,看官方文档给看懵了,试验了好几次才配成功,后面我们会根据
NODE_ENV 环境变量分别配置 dev mode server 和 prod mode serve;先来看看其功能:
支持两种模式的自动刷新(Automatic Refresh)
iframe模式
inline模式
支持热更新(Hot Module Replacement)
注: 自动刷新和热更新是两个概念
2.3.2 这里主要介绍自动刷新 inline 模式的配置,inline模式又分为两种配置:
命令行模式: 命令行模式只需要加上&--line
$ webpack-dev-server --line
Node.js API: 使用node.js api需要手动添加配置
var config = {
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
path.resolve(__dirname, 'app/index.js')
2.3.3 配置 Hot Module Replacement
这是webpack最牛逼的特性之一,即模块热替换,在前端代码变动的时候无需整个刷新页面,只把变化的部分替换掉。使用HMR功能也有两种配置方式:
命令行方式: 命令行模式只需要加上&--line --hot
&选项。&--hot&会自动把&webpack/hot/dev-server&加入到了webpack配置文件中的入口点。如果执行正确,可以在浏览器的控制台看到以下信息。
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
Node.js API: 手动配置需要做三件事情:
把&webpack/hot/dev-server
&加入到webpack配置文件的entry项
把new webpack.HotModuleReplacementPlugin()
&加入到webpack配置文件的plugins项
把&hot:true
&加入到webpack-dev-server的配置项里面
2.3.4 完整配置,主要分为三部分:
webpack.config.js: webpack常规配置,配置入口文件,输出文件,loaders等等
server.js: 将server部分分离到一个单独到的文件配置
package.json: 自定义启动命令
var webpack = require('webpack');
var path = require('path');
var config = {
path.resolve(__dirname, 'app/index.js')
// 定义入口文件
// 定义出口目录
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
publicPath: '/'
resolve: {
// resolve 指定可以被 import 的文件后缀
extensions: ['', '.js', '.jsx']
plugins: [
new webpack.HotModuleReplacementPlugin()
module.exports =
var webpack = require('webpack');
var webpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config.js');
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
contentBase: './app',
stats: { colors: true }
config.entry.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
server.listen(8080, "localhost", function(err) {
console.log(err);
console.log('Listening at localhost:8080...');
"scripts": {
"start": "node server.js"
现在你可以通过运行&npm start
&启动服务器来。
​​
博客等级:
博客积分:0
博客访问:10,160
关注人气:0
荣誉徽章:webpack构建vue项目(配置篇) - CSDN博客
webpack构建vue项目(配置篇)
最近公司要求用vue重构项目,还涉及到模块化开发,于是乎,我专门花了几天的时间研究了一下webpack这个目前来看比较热门的模块加载兼打包工具,发现上手并不是很容易,现将总结的一些有关配置的心得分享出来,欢迎大神来拍砖。。。
一、新建一个项目目录,cd /d 定位进去,然后输入npm init,会提示你填写一些项目的信息,一直回车默认就好了,或者直接执行npm init -y 直接跳过,这样就在项目目录下生成了一个package.json文件。
二、接下来就是通过npm安装项目依赖项,命令行输入:npm install babel-loader babel-core babel-plugin-transform-runtime babel-preset-es2015 babel-preset-stage-0 babel-runtime vue-loader vue-html-loader vue-hot-reload-api css-loader style-loader webpack webpack-dev-server --save-dev
,继续输入npm install vue@^1.0.26 --save 。
这里注意的几个点如下:
1.需要安装的依赖项视具体的项目需求来定,我只是安了几个必需的,后期会再加;
2.输入之后如果一直报错或者光标一直在转动,要么是npm版本太低(需要3+),要么将npm改成cnpm,如果没有安装淘宝NPM镜像,可以先输入npm install -g cnpm --registry=https://registry.npm.taobao.org,接着输入cnpm -v查看是否安装完成,然后就可以使用cnpm来代替npm;
3.可以先修改package.json文件中的devDependencies和dependencies,然后再输入npm install进行一次性安装(偷懒的做法,嘿嘿);
4.dependencies中的vue默认安装2+,如果dependencies中的vue选择^1.0.26,那么devDependencies中对应的vue-loader最好选择^7.3.0,vue-hot-reload-api最好选择^1.2.0,否则就会报错;
5.dependencies中的vue-router默认安装2+,无法识别router.map()这个方法,如果想要用回这个方法,最好选择^0.7.13;
6.有时安装一个依赖项,会提示还需要一并安装别的依赖项,例如:如果要安装bootstrap-loader,会提示要求安装node-sass sass-loader resolve-url-loader;要安装less-loader,会提示要求安装less;
完成这一步之后,会在项目目录下生成一个名node_modules的文件,对应的package.json文件中的内容变动如下(我额外添加了几个依赖项):
&devDependencies&: {
&autoprefixer-loader&: &^3.2.0&,
&babel-core&: &^6.18.2&,
&babel-loader&: &^6.2.7&,
&babel-plugin-transform-runtime&: &^6.15.0&,
&babel-preset-es2015&: &^6.18.0&,
&babel-preset-stage-0&: &^6.16.0&,
&babel-runtime&: &^6.18.0&,
&css-loader&: &^0.25.0&,
&debug&: &^2.2.0&,
&express&: &^4.14.0&,
&extract-text-webpack-plugin&: &^1.0.1&,
&file-loader&: &^0.9.0&,
&html-webpack-plugin&: &^2.24.1&,
&jquery&: &^3.1.1&,
&less&: &^2.7.1&,
&less-loader&: &^2.2.3&,
&style-loader&: &^0.13.1&,
&url-loader&: &^0.5.7&,
&vue-hot-reload-api&: &^1.2.0&,
&vue-html-loader&: &^1.2.3&,
&vue-loader&: &^7.3.0&,
&webpack&: &^1.13.3&,
&webpack-dev-middleware&: &^1.8.4&,
&webpack-dev-server&: &^1.16.2&,
&webpack-hot-middleware&: &^2.13.1&
&dependencies&: {
&vue&: &^1.0.26&,
&vue-router&: &^0.7.13&
三、在项目目录下新建一个名为src的目录,里面用于存放入口文件(index.js)、项目源文件(html,css,js,img之类的)、组件(.vue后缀),我的src目录结构大致如下:
-components
-index.html
当然,有输入目录,就有输出目录,即在项目目录下新建一个output目录,用于放置生产出来的各种资源文件。
四、在项目目录下新建一个名为build目录,里面用于存放各种配置文件,涉及到基础配置、开发和生产环境、静态服务器以及热加载,详细的内容请看下面的代码:
1.webpack.config.js(基础配置文件)
// 引入依赖模块
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
// 入口文件,路径相对于本文件所在的位置,可以写成字符串、数组、对象
// path.resolve([from ...], to) 将to参数解析为绝对路径
index:path.resolve(__dirname, '../src/entry/index.js'),
// 需要被提取为公共模块的群组
vendors:['vue','vue-router','jquery'],
// 输出配置
// 输出文件,路径相对于本文件所在的位置
path: path.resolve(__dirname, '../output/static/js/'),
// 设置publicPath这个属性会出现很多问题:
// 1.可以看成输出文件的另一种路径,差别路径是相对于生成的html文件;
// 2.也可以看成网站运行时的访问路径;
// 3.该属性的好处在于当你配置了图片CDN的地址,本地开发时引用本地的图片资源,上线打包时就将资源全部指向CDN了,如果没有确定的发布地址不建议配置该属性,特别是在打包图片时,路径很容易出现混乱,如果没有设置,则默认从站点根目录加载
// publicPath: '../static/js/',
// 基于文件的md5生成Hash名称的script来防止缓存
filename: '[name].[hash].js',
// 非主入口的文件名,即未被列在entry中,却又需要被打包出来的文件命名配置
chunkFilename: '[id].[chunkhash].js'
// 其他解决方案
resolve: {
// require时省略的扩展名,遇到.vue结尾的也要去加载
extensions: ['','.js', '.vue'],
// 模块别名地址,方便后续直接引用别名,无须写长长的地址,注意如果后续不能识别该别名,需要先设置root
// 不进行打包的模块
externals:{},
// 模块加载器
// loader相当于gulp里的task,用来处理在入口文件中require的和其他方式引用进来的文件,test是正则表达式,匹配要处理的文件;loader匹配要使用的loader,&-loader&可以省略;include把要处理的目录包括进来,exclude排除不处理的目录
loaders: [
使用vue-loader 加载 .vue 结尾的文件
test: /\.vue$/,
loader: 'vue-loader',
exclude: /node_modules/
// 使用babel 加载 .js 结尾的文件
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
presets: ['es2015', 'stage-0'],
plugins: ['transform-runtime']
// 使用css-loader和style-loader 加载 .css 结尾的文件
test: /\.css$/,
// 将样式抽取出来为独立的文件
loader: ExtractTextPlugin.extract(&style-loader&, &css-loader!autoprefixer-loader&),
exclude: /node_modules/
// 使用less-loader、css-loader和style-loade 加载 .less 结尾的文件
test: /\.less$/,
// 将样式抽取出来为独立的文件
loader: ExtractTextPlugin.extract(&style-loader&, &css-loader!autoprefixer-loader!less-loader&),
exclude: /node_modules/
// 加载图片
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
// 把较小的图片转换成base64的字符串内嵌在生成的js文件里
limit: 10000,
// 路径要与当前配置文件下的publicPath相结合
name:'../img/[name].[ext]?[hash:7]'
// 加载图标
test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
loader: 'file-loader',
// 把较小的图标转换成base64的字符串内嵌在生成的js文件里
limit: 10000,
name:'../fonts/[name].[ext]?[hash:7]',
prefix:'font'
// 配置插件项
plugins: []
2.webpack.dev.config.js(开发环境下的配置文件)
// 引入依赖模块
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
// 引入基本配置
var config = require('./webpack.config.js');
// 必须修改原配置中网站运行时的访问路径,相当于绝对路径,修改完之后,当前配置文件下的很多相对路径都是相对于这个来设定;
// 注意:webpack-dev-server会实时的编译,但是最后的编译的文件并没有输出到目标文件夹,而是保存到了内存当中
config.output.publicPath = '/';
// 重新配置模块加载器
config.module= {
// test是正则表达式,匹配要处理的文件;loader匹配要使用的loader,&-loader&可以省略;include把要处理的目录包括进来,exclude排除不处理的目录
loaders: [
使用vue-loader 加载 .vue 结尾的文件
test: /\.vue$/,
loader: 'vue-loader',
exclude: /node_modules/
// 使用babel 加载 .js 结尾的文件
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
presets: ['es2015', 'stage-0'],
plugins: ['transform-runtime']
// 使用css-loader、autoprefixer-loader和style-loader 加载 .css 结尾的文件
test: /\.css$/,
// 将样式抽取出来为独立的文件
loader: ExtractTextPlugin.extract(&style-loader&, &css-loader!autoprefixer-loader&),
exclude: /node_modules/
// 使用less-loader、autoprefixer-loader、css-loader和style-loade 加载 .less 结尾的文件
test: /\.less$/,
// 将样式抽取出来为独立的文件
loader: ExtractTextPlugin.extract(&style-loader&, &css-loader!autoprefixer-loader!less-loader&),
exclude: /node_modules/
// 加载图片
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
// 把较小的图片转换成base64的字符串内嵌在生成的js文件里
limit: 10000,
// 路径和生产环境下的不同,要与修改后的publickPath相结合
name: 'img/[name].[ext]?[hash:7]'
// 加载图标
test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
loader: 'file-loader',
limit: 10000,
// 路径和生产环境下的不同,要与修改后的publickPath相结合
name:'fonts/[name].[ext]?[hash:7]',
prefix:'font'
// 重新配置插件项
config.plugins = [
// 位于开发环境下
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '&development&'
// 自动生成html插件,如果创建多个HtmlWebpackPlugin的实例,就会生成多个页面
new HtmlWebpackPlugin({
// 生成html文件的名字,路径和生产环境下的不同,要与修改后的publickPath相结合,否则开启服务器后页面空白
filename: 'src/pages/index.html',
// 源文件,路径相对于本文件所在的位置
template: path.resolve(__dirname, '../src/pages/index.html'),
// 需要引入entry里面的哪几个入口,如果entry里有公共模块,记住一定要引入
chunks: ['vendors','index'],
// 要把&script&标签插入到页面哪个标签里(body|true|head|false)
inject: 'body',
// 生成html文件的标题
// hash如果为true,将添加hash到所有包含的脚本和css文件,对于解除cache很有用
// minify用于压缩html文件,其中的removeComments:true用于移除html中的注释,collapseWhitespace:true用于删除空白符与换行符
// 提取css单文件的名字,路径和生产环境下的不同,要与修改后的publickPath相结合
new ExtractTextPlugin(&[name].[contenthash].css&),
// 提取入口文件里面的公共模块
new monsChunkPlugin({
name: 'vendors',
filename: 'vendors.js',
// 为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
new webpack.optimize.OccurenceOrderPlugin(),
// 模块热替换插件
new webpack.HotModuleReplacementPlugin(),
// 允许错误不打断程序
new webpack.NoErrorsPlugin(),
// 全局挂载插件
new webpack.ProvidePlugin({
$:&jquery&,
jQuery:&jquery&,
&window.jQuery&:&jquery&
// vue里的css也要单独提取出来
config.vue = {
loaders: {
css: ExtractTextPlugin.extract(&css&)
// 启用source-map,开发环境下推荐使用cheap-module-eval-source-map
config.devtool='cheap-module-eval-source-map';
// 为了实现热加载,需要动态向入口配置中注入 webpack-hot-middleware/client ,路径相对于本文件所在的位置
// var devClient = 'webpack-hot-middleware/client';
// 为了修改html文件也能实现热加载,需要修改上面的devClient变量,引入同级目录下的dev-client.js文件
var devClient = './build/dev-client';
// Object.keys()返回对象的可枚举属性和方法的名称
Object.keys(config.entry).forEach(function (name, i) {
var extras = [devClient];
config.entry[name] = extras.concat(config.entry[name]);
module.exports =
3.webpack.prod.config.js(生产环境下的配置文件)
// 引入依赖模块
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
// 引入基本配置
var config = require('./webpack.config');
// 重新配置插件项
config.plugins = [
// 位于生产环境下
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '&production&'
// 自动生成html插件,如果创建多个HtmlWebpackPlugin的实例,就会生成多个页面
new HtmlWebpackPlugin({
// 生成html文件的名字,路径相对于输出文件所在的位置
filename: '../../html/index.html',
// 源文件,路径相对于本文件所在的位置
template: path.resolve(__dirname, '../src/pages/index.html'),
// 需要引入entry里面的哪几个入口,如果entry里有公共模块,记住一定要引入
chunks: ['vendors','special','index'],
// 要把&script&标签插入到页面哪个标签里(body|true|head|false)
inject: 'body',
// 生成html文件的标题
// hash如果为true,将添加hash到所有包含的脚本和css文件,对于解除cache很有用
// minify用于压缩html文件,其中的removeComments:true用于移除html中的注释,collapseWhitespace:true用于删除空白符与换行符
// 提取css单文件的名字,路径相对于输出文件所在的位置
new ExtractTextPlugin(&../css/[name].[contenthash].css&),
// 提取入口文件里面的公共模块
new monsChunkPlugin({
name: 'vendors',
filename: 'vendors.js',
// 压缩js代码
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
// 排除关键字,不能混淆
except:['$','exports','require']
// 为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
new webpack.optimize.OccurenceOrderPlugin(),
// 全局挂载插件,当模块使用这些变量的时候,wepback会自动加载,区别于window挂载
new webpack.ProvidePlugin({
$:&jquery&,
jQuery:&jquery&,
&window.jQuery&:&jquery&
// vue里的css也要单独提取出来
config.vue = {
loaders: {
css: ExtractTextPlugin.extract(&css&)
// 开启source-map,生产环境下推荐使用cheap-source-map或source-map,后者得到的.map文件体积比较大,但是能够完全还原以前的js代码
config.devtool='source-map';
// 关闭source-map
// config.devtool=
module.exports =
4.dev-server.js(服务器配置文件)
// 引入依赖模块
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.dev.config.js');
// 创建一个express实例
var app = express();
// 对网站首页的访问返回 &Hello World!& 字样
app.get('/', function (req, res) {
res.send('Hello World!');
// 调用webpack并把配置传递过去
var compiler = webpack(config);
// 使用 webpack-dev-middleware 中间件,搭建服务器
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: config.output.publicPath,
colors: true,
chunks: false
// 使用 webpack-hot-middleware 中间件,实现热加载
var hotMiddleware = require('webpack-hot-middleware')(compiler);
// 为了修改html文件也能实现热加载,使用webpack插件来监听html源文件改变事件
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
// 发布事件
hotMiddleware.publish({ action: 'reload' });
// 注册中间件
app.use(devMiddleware);
app.use(hotMiddleware);
// 监听 8888 端口,开启服务器
app.listen(8888, function (err) {
if (err) {
console.log(err);
console.log('Listening at http://localhost:8888');
5.dev-client.js(配合dev-server.js监听html文件改动也能够触发自动刷新)
// 引入 webpack-hot-middleware/client
var hotClient = require('webpack-hot-middleware/client');
// 订阅事件,当 event.action === 'reload' 时执行页面刷新
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload();
五、为了不必每次构建项目都要输入webpack --display-modules --display-chunks --config build/webpack.config.js这条长命令,我们在package.js文件中修改“scripts”项:
&scripts&: {
&build&:&webpack --display-modules --display-chunks --config build/webpack.config.js&,
&dev&:&node ./build/dev-server.js&
注意:package.js中不能有注释。
这样,我们就可以通过执行&npm run build&来进行构建,同时还增加了一条开启开发服务器的命令&npm run dev。
六、网上很多人讲解webpack配置是按“先……然后……”的逻辑往下走,以及每走一步会说明走这一步的原因是什么,配完之后的结果是什么,出了问题该怎么解决,这种撰文方式确实帮了很多入门webpack的小白们(譬如我)很大的忙。所以这里我就省略了这些步骤,而是直接将最后一步的配置结果展现出来给大家看,并且附上了详细的注释(写得呕心沥血啊~)供大家理解,以后不出意外应该会出webpack构建vue的进阶篇,敬请期待~
本文已收录于以下专栏:
相关文章推荐
vue-loader的概念其他loader:css-loader、url-loader、html-loader等
先来了解一下模块的概念,比如在nodeJS中,有require和exports关键字...
Vue.js build set-up from scratch with webpack, vue-loader and hot reload
正文Vue.JS 是我现在最喜欢的...
由于最近在vue-cli生成的webpack模板项目的基础上写一个小东西,开发过程中需要改动到build和config里面一些相关的配置,所以刚好趁此机会将所有配置文件看一遍,理一理思路,也便于以后修...
上个项目第一次用到vue+webpack,也是我第一次尝试自动化、模块化的开发方式,总的来说就是结构太烂,开发体验差,效率低,难维护。细数的罪状有如下几条
没有servies层,全部ajax接口都和逻...
webpack配置起来确实麻烦,这不,之前用刚配好了vue1+的版本,结果在(部分)安卓机上测试,发现存在开启热加载(dev-server)的情况下不能识别vue语法的问题,试了很多方法,都没能很好的...
我一直想试着一下翻译别人的文章,因为总是觉得自己的文章写的不是很好。希望从中学习一下。
原文Vue.js build set-up from scratch with webpack, vue-lo...
当前最流行的框架和构建工具
Vue2+VueRouter2+webpack 构建项目实战(一)准备工作之前写的博客没有采用打包工具,而是直接引用js的方式来做的。这种方式很扯淡,也因此,我写了三篇博客之后就没有再写了。通过几个月...
Vue-webpack项目配置详解1、首先我们在构建vue项目后,就得先了解vue的项目结构├── build --------------------------------- webpack相关配...
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)使用webpack与vue2.0构建前端工程(一) - CSDN博客
使用webpack与vue2.0构建前端工程(一)
组件化开发和前后端分离是如今前端的发展趋势。
目前我在工作中采用的项目,基本上是jquery+bootstrap构建的,也没有采用任何的前端构建工具,碰到比较多的问题是经常需要进行dom操作,业务逻辑没办法和数据流解耦,导致后端接口更改或者前端页面有变动时,原来的代码逻辑都很难更改,所以这个系列的文章会讨论怎么把前端工程从原来的模式中解耦出来。
说到前端,最火的目前就是angular、react、vue三者了,考虑到vue的学习曲线相比前两个低(其实我是最先学的react),所以就采用了vue2.0我一直是一个不太喜欢写样式(css less)的人,因为我觉得自己对审美并不是有很高的天赋,而且自己也不喜欢为了一个样式扣半天。所以就考虑直接采用现成的css样式,组件的话复用一部分,自己写一部分。找了很多资料,采用了element饿了么的前端组件,这个组件由vue2.0构建,目前已经被应用于实际业务场景,详细文档可以访问
采用了组件化开发之后,随之而来的问题是,如何单独把前端项目从原来的开发模式中抽离出来,并且又可以在必要的时候整合到后端项目中,为了解决这个问题,我们用到的工具有
1.webpack 官网:
2.node-glob github地址:
3.webpack-plugin包括:html-webpack-plugin(打包html),extract-text-webpack-plugin(抽离CSS文件)
1.采用webpack打包文件,按需引入js和css
2.采用vue2.0组件化开发方式
3.根据项目需要,使用npm run dev和npm run build 可以分别运行dev脚本和build脚本进行不同的构建操作,dev脚本可以直接在本地建立一个服务器,直接查看我们的前端demo,实现前端代码的热部署,并且根据需要,可以将一些API请求转发到实际的后端服务器上,获取相应的json数据;build脚本可以根据我们的后台项目需要把页面打包发布,然后把这个包丢给后端的同学们就可以了!
采用webpack打包
webpack是目前十分流行的一个打包工具,可以把任何静态资源按需引入。关于webpack,建议查看它的官网(上面有),这不是本文重点,只做简要介绍,如果你还对webpack不太熟悉,那么你最好先学习一下这个工具。另外推荐一下慕课网关于webpack的学习课程,,非常好的课程!
vue2.0这个也不做太多介绍了,官网文档十分齐全。
开始我们的工程
作为一个懒人,肯定不可能从npm init开始建立一个工程,所以我一开始就采用了项目模板
element快速上手模板:
主要是webpack配置项比较多,js css loader配置基本大同小异,我们姑且就在这个项目模板基础上更改 代码目录大概是这样的
饿了么快速上手模板工程
来看看它的webpack配置怎么写的
} = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const url = require('url')
const publicPath = ''
module.exports = (options = {}) =& ({
vendor: './src/vendor',
index: './src/main.js'
path: resolve(__dirname, 'dist'),
filename: options.dev ? '[name].js' : '[name].js?[chunkhash]',
chunkFilename: '[id].js?[chunkhash]',
publicPath: options.dev ? '/assets/' : publicPath
test: /\.vue$/,
use: ['vue-loader']
test: /\.js$/,
use: ['babel-loader'],
exclude: /node_modules/
test: /\.html$/,
loader: 'html-loader',
options: {
root: resolve(__dirname, 'src'),
attrs: ['img:src', 'link:href']
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
test: /favicon\.png$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
exclude: /favicon\.png$/,
loader: 'url-loader',
options: {
limit: 10000
plugins: [
new monsChunkPlugin({
names: ['vendor', 'manifest']
new HtmlWebpackPlugin({
template: 'src/index.html'
resolve: {
'~': resolve(__dirname, 'src')
devServer: {
host: '127.0.0.1',
port: 8010,
'/api/': {
target: 'http://127.0.0.1:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
historyApiFallback: {
index: url.parse(options.dev ? '/assets/' : publicPath).pathname
devtool: options.dev ? '#eval-source-map' : '#source-map'
首先,webpack的config需要以commonjs规范返回一个config对象,这意味着我们可以在里面写任意的逻辑,在这里面它写成了通过函数(ES6箭头函数)返回对象的格式,好处是可以读取到命令行参数,这样子就可以根据产品和开发环境来进行不同的配置。(options.dev有值则为开发环境)
值得一提的是,这里这个项目模板已经为我们配置了devServer,项目中的package.json里面也已经加入了相关依赖,webpack-dev-server可以让我们实现热插拔,还可以设置代理进行URL转发,这也是我们前端脱离后端的基础。
这个配置文件已经为我们处理好了.vue,.css,.less,.sass和各种格式的图片文件(参见loader部分),并且采用了HtmlWebpackPlugin来打包html,同时它将公共的element组件部分抽出打包成vendor,利用了CommonsChunkPlugin来打包,避免对整个element组件的重复打包(commonsChunkPlugin中的manifest是指清单文件,本文不细讲)。
看起来好像已经挺完备的了,但是这个工程的打包入口只有一个,生成的html也只有一个,如果你需要打包多个html页面,那么意味着你需要自己在plugins中自己添加新的htmlWebpackPlugin配置和打包入口配置,而在一些大一点的工程项目中,我们的html页面往往有很多个,如果每次都要添加配置,就非常的繁琐了,有没有办法能让它自动写上配置呢?
参考了这个项目里面的做法,我决定采用glob来读取项目中所有的.html文件,并且遵循一定的规则来自动匹配相应的入口文件,并把配置项写入到我们的config对象中。在这里我们默认约定大于配置,也就是我们的项目目录必须要遵循一定的约定,下面是我们项目的目录结构
├── dist&&&&&&&&&&&&&&&&&&&&&&& # 打包后项目的文件地址
├── node_modules&&&&&&&&&&&&&&& # 依赖
├── src&&&&&&&&&&&&&&&&&&&&&&&& # 项目代码
│&&& ├── assets&&&&&&&&&&&&&&&& # 静态资源文件
│&&& │& &&├── css&&&&&&&&&&&&&& # css
│&&& │&&& ├── img&&&&&&&&&&&&&& # img
│&&& ├── common&&&&&&&&&&&&&&&& # 公共文件
│&&& │&&& ├── config.js&&&&&&&& # 公共配置文件
│&&& ├── pages&&&&&&&&&&&&&&&&& # vue组件及入口文件 按模块划分
│&&& │&&& ├── college & & & & & & # college模块(假设有一个模块为college)
│&&&&│&&&&│&&&
├── index # index模块(假设有一个模块为college)
│&&& │&&& │&&&
│&&&&├── App.vue&&&&& # index 主vue组件
│&&& │&&& │ & &│&&&&├── index.js&&&&& # index 主入口index.js
│&&& │&&& │&&&
│ & &├── index.html&& # index html模板 用于vue组件渲染
│&&&&│&&&&│&&& ├── login & & & & & & & & &# login模块(假设有一个模块为college)
│&&& │&&& │&&&&│&&&&├── App.vue&&&&& # index 主vue组件
│&&& │&&& │ & &│&&&&├── login.js&&&&& # index 主入口login.js
│&&& │&&& │&&&&│ & &├── login.html&& #
login&html模板 用于vue组件渲染
│&&& ├── components&&&&&&&&&&&& # vue组件 按三个层级划分 (公共组件|模块公共组件|页面组件)
│&&& │&&& ├── common&&&&&&&&&&& # 公共组件
│&&& │&&& ├── index_common &# 模块公共组件
├── webpack.config.js& & & & & &# webpack配置文件
├──&package.json & & & & & & & &&&# 项目配置文件
├── postcss.config.js& & & & & & &# postcss配置文件(编译CSS)
├──&makefile & & & & & &
├──&README.md
1.代码根目录主要由src dist两个文件夹,src即我们的前端工程代码,dist则是打包后的demo
2.assets存放静态资源文件
3.common存放一些前端的公共文件(例如配置文件可以保存开发环境和产品环境下的api接口地址)
4.pages则是我们的所有页面入口,里面按照模块分为两级,例如学院模块下可能有login index模块,每个子模块下会有一个主要的.vue,.js,.html文件,分别是主组件(绑定到元素),入口文件,和html模板。
5.components下存放所有的.vue组件,组件按照三个层级划分,即公共组件|模块公共组件|页面级组件,页面级组件可写在components下也可以直接写在模块文件夹中,直接按需引入。
有了以上这些约定,我们就可以让webpack来识别html文件和入口文件了。
首选处理打包入口:
//此处用于找到所有pages下的入口js,并写入webpack的entry配置中
glob.sync('./src/pages/**/*.js').forEach(path =& {
const chunk = path.split('./src/pages/')[1].split('.js')[0]
if(chunk.split('/').length &=2){
// console.log(chunk);
nocommChunks.push(chunk);
entries[chunk] = path
chunks.push(chunk)
})这段代码的意思是,遍历所有的pages下的以js结尾的文件,写入到我们的打包入口变量entries中,里面有一点trick是我们创建了一个一个非公共组件的chunks数组集合nocommChunks,这个在后面会用到。
然后用同样的方法处理html
//此处用于找到所有pages下的html模板,并采用htmlWebpackPlugin进行加载
//生产环境下 打包生成的html会放在 /dist/view/模块名 文件夹中
glob.sync('./src/pages/**/*.html').forEach(path =& {
// console.log(path);
const allPath = path.split('./src/pages/')[1].split('.html')[0];
const modulename = path.split('./src/pages/')[1].split('.html')[0].split('/')[0];
const pagename = path.split('./src/pages/')[1].split('.html')[0].split('/')[1];
const filename = '/view/' + modulename + '/' + pagename + '.html'
// const chunk =
path.split('./src/pages/')[1].split('.html')[0]
let tempChunks = nocommChunks.slice(0);
tempChunks.remove(allPath);
const htmlConf = {
filename: filename,
template: path,
excludeChunks:tempChunks
if(options.dev){
delete htmlConf.
const newHtmlPlugin = new HtmlWebpackPlugin(htmlConf)
plugins.push(newHtmlPlugin)
这里面值得提的是,如果我们没有加上excludeChunks,那么打包后College/index/index.html和Collge/login/login.html都会把彼此的chunk也给引用上,也就是index.html中会有login.js打包后的代码块,login.html中会有index.js打包后的代码块,这显然不是我们想要的结果,所以我们这里把所有的非公共组件加到一个chunks中,再根据名字,把不属于自己的东西加入到excludeChunks,就避免了互相引用的问题。
最后,原来的项目模板里面没有把公共的CSS打包成一个模块,我们采用了ExtractTextPlugin模块来完成这个操作,详细可以看看我的注释
test: /\.css$/,
//这是一个坑,网上很多教程写的是ExtractTextPlugin.extract([&style-loader&,&css-loader&])
//实际上这种写法已经被抛弃,会导致webpack报错
//应采用以下这种写法
use: ExtractTextPlugin.extract({
fallback:&style-loader&,
use : &css-loader&
最后我们还希望打包后的目录能够直接与我们的后端项目相匹配,目前我的一个项目采用的是egg.js,它需要的打包后的目录如下:
├── dist&&&&&&&&&&&& # main
│&&& ├── public&&& # 静态资源文件
│&&& │&&& ├── css&& # css
│&&& │&&& └── font& # font
│&&& │&&& └── img&& # img
│&&& │&&& └── js & & &# js&
│&&& ├── components # components
│&&& └── view&&&&& &# html文件 按模块划分
│& & &│&&├──college
│& & &│&&&├──college
│& & &│&&&├──login
以上代码已经发布至github&
本文已收录于以下专栏:
相关文章推荐
npm init -y 初始化项目
安装各种依赖项
npm install --save vue 安装vue2.0
npm install --save-dev webpack@^2...
Vue目前的开发模式主要有两种
1.直接页面级的开发,script直接引入Vue
2.工程性开发,webpack+loader或者直接使用脚手架工具Vue-cli,里面的文件都配置好了,webpack...
Vue2+VueRouter2+webpack 构建项目实战(一)准备工作之前写的博客没有采用打包工具,而是直接引用js的方式来做的。这种方式很扯淡,也因此,我写了三篇博客之后就没有再写了。通过几个月...
Vue 2.0 兼容了绝大部分的 1.0 模板语法,仅废弃掉了其中的一小部分。这些模板在背后被编译成了 Virtual DOM 渲染函数,但是如果用户需要更复杂的 JavaScript,也可以选择在其...
上个项目第一次用到vue+webpack,也是我第一次尝试自动化、模块化的开发方式,总的来说就是结构太烂,开发体验差,效率低,难维护。细数的罪状有如下几条
没有servies层,全部ajax接口都和逻...
1.下载vue-cli
npm install vue-cli -g
vue-cli的使用与详细介绍,可以到github上获取/vuejs/vue-cli
作为 Vue 的使用者我们对于 vue-cli 都很熟悉,但是对它的 webpack 配置我们可能关注甚少,今天我们为大家带来 vue-cli#2.0 的 webpack 配置分析
vue2.0新手发车(一):使用webpack构建项目作者:KoviiMa环境搭建:
安装vue-cli
npm install -g vue-cli
创建vue项目
语法:vue init
直接上代码:
#durationbar{
width: 500
height: 20
#durationbar progress{
#0注册GitHub账号
*1)到/注册GitHub账号
#1在GitHub上建立GitHub仓库
*1)登录后点击右下方的“new repository”按...
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 webpack打包普通项目 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信