代码在github上,有需要的可以查阅
首先我们要知道
webpack是什么?
webpack
是当下最热门的模块化管理和打包工具
如何安装webpack
安装webpack
之前需要安装Node.js
,Node.js
带了包管理工具npm
安装后执行
npm install webpack -g //全局安装
如果是依赖于package.json
安装的话
创建一个文件夹
sudo mkdir webpacktest
//赋予权限
sudo chmod 777 webpacktest
//初始化,与cli进行交互的方式 强制可加 -y 生成默认的package.json
npm init
之后会生成一个package.json
的文件
因为不同的项目需要不同webpack
的版本,建议将webpack
安装到项目依赖
npm install webpack@2.0.0.x --save-dev
webpack
骨架
说了这么多,让我们了解一下webpack的骨架是什么样的呢?
简易的目录结构如下:
webpacktest
-app
-Greeter.js
-main.js
-public
-index.js
-webpack.config.js
index.html文件只有最基础的html代码,它唯一的目的就是加载打包后的js文件(bundle.js是不存在的)
<html lang="en">
<head>
<meta charset="utf-8">
<title>Webpack Sample Project</title>
</head>
<body>
<div id='root'>
</div>
<script src="bundle.js"></script>
</body>
</html>
Greeter.js只包括一个用来返回包含问候信息的html元素的函数。
var greeter = require('./Greeter.js');
document.getElementById('root').appendChild(greeter());
main.js用来把Greeter模块返回的节点插入页面。
// Greeter.js
module.exports = function() {
var greet = document.createElement('div');
greet.textContent = "Hi there and greetings!";
return greet;
};
创建webpack.config.js
module.exports = {
entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "bundle.js"//打包后输出文件的文件名
}
}
如何将文件打包???
1 _执行webpack
2 _检测到文件变化就进行打包(需要刷新浏览器): webpack --watch
3 _检测文件变化就进行打包(不需要刷新浏览器)
我们需要引入一个新的插件:webpack-dev-server
webpack-dev-server 又是什么?
webpack-dev-server是一个小型的node.js,Express服务器
webpack-dev-server有两种模式支持自动刷新——iframe模式和inline模式
- 在iframe模式下:页面是嵌套在一个iframe下的,在代码发生改动的时候,这个iframe会重新加载
- 在inline模式下:一个小型的webpack-dev-server客户端会作为入口文件打包,这个客户端会在后端代码改变的时候刷新页面(常用)
那么我们执行webpack-dev-server --inline --hot
进行热备 Notice:不产出任何文件
既然这样打包文件用第三个方法就可以了,前两个要他何用?
上线部署的时候不可能将使用热备方案将进行加载,只有用前两种方案将文件记性访问,并配置服务器端的访问路径
什么是vue.js
vue的安装方式
- 独立版本 |
<script></script>
直接引入 - npm 安装 |
npm install vue --save
vue官方有脚手架我们为什么还要自己构建?
官方提供的vue-cli
是单页面不支持多页面的。
那么开始构建vue多页面入口吧
我的webpack.config.js
如下
/**
* 主入口文件
* @email:gewenrui0.0@gmail.com
* @type {glob}
*/
const glob = require('glob');
const util = require('./util');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//防止打包文件过大
// externals:{
// 'vue':'window.vue'
// },
// 使用sourcemap的话 300kB -> 1.1 Mb
//devtool: 'eval-source-map',
entry: util.getEntries('./src/module/**/*.js'),
output: {
path: __dirname + '/dist',
//实际webpack-dev-sever 打包Js 访问的位置
publicPath: '/dist',
//filename: '[name].[hash:5].js' hash 表示对文件进行hash化
filename: '[name].js'
},
//定义解析模块时路径的配置
resolve: {
//require时省略参数的扩展名
extensions: ['.js', '.vue', '.json'],
//创建别名
alias: {
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '/src/assets'),
'components': path.resolve(__dirname, '../src/components'),
//引入vue.common js
'vue$': 'vue/dist/vue.common.js'
}
},
module: {
//webpack2.0写法,引用vue-loader
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
},
{
test: /\.js/,
use: ['babel-loader'],
exclude: '/node_modules/'
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
loader: 'file-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/,
loader: 'file-loader',
query: {
name: '[name].[ext]?[hash]'
}
}
]
},
plugins: [
//有可能因为webpack版本不兼容导致缺失问题
new HtmlWebpackPlugin({
inject: true,
title: '关于我们',
//加上一个hash值,防缓存
hash: true,
chunks: ['about', 'common'],
//公共模板文件 TODO:此处如果使用公共模板的话需要引入webpack公共的方法
template: './template.ejs',
//生成文件的名称
filename: '../src/module/about/about.html'
}),
new HtmlWebpackPlugin({
inject: true,
title: '首页',
//加上一个hash值,防缓存
hash: true,
chunks: ['index', 'common'],
//公共模板文件
template: './template.ejs',
//生成文件的名称
filename: '../src/module/index/index.html'
}),
//公共类库单独打包
new webpack.optimize.CommonsChunkPlugin('common'),
//打包代码
//new webpack.optimize.UglifyJsPlugin(),
//增加copyRight
//new webpack.BannerPlugin("gewenrui's webpack"),
]
}
依赖文件如下:
var glob = require('glob');
//引入glob 进行地址分割
exports.getEntries = function (globPath) {
var entries = {}
/**
* 读取src目录,并进行路径裁剪
*/
glob.sync(globPath).forEach(function (entry) {
/**
* path.basename 提取出用 ‘/' 隔开的path的最后一部分,除第一个参数外其余是需要过滤的字符串
* path.extname 获取文件后缀
*/
// var basename = path.basename(entry, path.extname(entry), 'router.js') // 过滤router.js
// ***************begin***************
// 当然, 你也可以加上模块名称, 即输出如下: { module/main: './src/module/index/main.js', module/test: './src/module/test/test.js' }
// 最终编译输出的文件也在module目录下, 访问路径需要时 localhost:8080/module/index.html
// slice 从已有的数组中返回选定的元素, -3 倒序选择,即选择最后三个
var tmp = entry.split('/').splice(-3)
var moduleName = tmp.slice(1, 2);
// ***************end***************
entries[moduleName] = entry
});
// 获取的主入口如下: { main: './src/module/index/main.js', test: './src/module/test/test.js' }
return entries;
}
package.json
如下
{
"name": "vue_final",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node webpack.dev.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.24.0",
"babel-loader": "^6.4.1",
"babel-plugin-component": "^0.9.1",
"babel-preset-es2015": "^6.24.0",
"css-loader": "^0.27.3",
"element-ui": "^1.1.2",
"file-loader": "^0.10.1",
"glob": "^7.1.1",
"html-loader": "^0.4.5",
"html-webpack-plugin": "^2.28.0",
"style-loader": "^0.16.0",
"vue": "^2.2.4",
"vue-hot-reload-api": "^2.0.11",
"vue-loader": "^11.1.4",
"vue-router": "^2.3.0",
"vue-template-compiler": "^2.2.4",
"webpack": "^2.2.1",
"webpack-dev-middleware": "^1.10.1",
"webpack-dev-server": "^2.4.2",
"webpack-hot-middleware": "^2.17.1"
}
}
以上构建方式都在代码里面了,使用Webpack构建多入口文件还是会出现很多坑的~