webpack
webpack是德国开发者Tobias Koppers开发的模块加载器。
安装
npm install webpack -g
webpack工作流程
webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
webpack会把加载入口文件main.js,分析这个文件依赖的模块然后统一打包到bundle.js。
webpack loader
Loader可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。
Loader的特性:
- 可以通过管道方式链式调用,每个loader可以把资源转换成任意格式并传递给下一个loader,但是最后一个loader必须返回javascript。
- 可以同步或一部执行
- 运行在node.js环境中,可以完成任何node.js程序可以胜任的任务
- 可以接受参数
- 可以通过文件扩展名或正则表达式绑定不同类型的文件
- 可以通过npm来发布跟安装
- 可以访问配置
- 插件可以让loader拥有更多特性
- 可以分发出附加的任意文件
可以说loader是webpack的核心
常用loader
- css-loader 读取css文件
- style-loader 把css插入页面中
- url-loader 将图片转成base64
webpack配置
var webpack = require('webpack');
module.exports = {
entry: ['./entry.js'], //数组,允许有多个入口
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [{
test: /.css$/,
loader: 'style!css'
}]
}
};
webpack辅助
当项目逐渐变大,webpack的编译时间会变长,可以通过参数让编译输出的内容带有进度和颜色
webpack --progress --color
//other commands
webpack #最基本的启动webpack命令
webpack -w #提供watch方法,实时进行打包更新
webpack -p #对打包后的文件进行压缩
webpack -d #提供SourceMaps,方便调试
webpack --colors #输出结果带彩色,比如:会用红色显示耗时较长的步骤
webpack --profile #输出性能数据,可以看到每一步的耗时
webpack --display-modules #默认情况下 node_modules 下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块
开启监听模式
webpack --watch
开启监听模式后,没有改变的模块会在编译后缓存到内存中,而不会每次都被重新编译,可以不用每次等待漫长的build
webpack+vue
webpack.config.js
var path = require('path');
module.exports = {
entry: './src/main',
output: {
path: path.join(__dirname, './dist'), //文件地址,使用绝对路径
filename: '[name].js',
publicPath: '/dist/' //公共文件生成的地址
},
devServer: {
historyApiFallback: true,
hot: false,
inline: true,
grogress: true
},
//加载器
module: {
//loader 的执行顺序是从右至左滴
loaders: [
{ test: /.vue$/, loader: 'vue' }, //解析.vue文件
{ test: /.js$/, loader: 'babel', exclude: /node_modules/ }, //ES6
{ test: /.css$/, loader: 'style!css!autoprefixer' }, //编译css并自动添加css前缀
{ test: /.scss$/, loader: 'style!css!sass?sourceMap' }, //编译sass
{ test: /.(png|jpg|gif)$/, loader: 'url-loader?limit=8192' },
{ test: /.(html|tpl)$/, loader: 'html-loader'}
]
},
//vue-loader配置
vue: {
loaders: {
css: 'style!css!autoprefixer'
}
},
// babel-loader配置, 转换成ES6语法(ES2015)
babel: {
presets: ['es2015'],
plugins: ['transform-runtime']
},
resolve: {
// require时省略扩展名,如 require('some') 即可,不需写 some.js
extensions: ['', '.js', '.vue'],
// 别名,可以理解成定义一个常量 fitler = 'dirname/src/filters'
alias: {
filter: path.join(__dirname, './src/filters'),
components: path.join(__dirname, './src/components')
},
//开启source-map,webpack有多种source-map,在官网文档可以查看
devtool: 'eval-source-map'
}
};
入口文件
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
import index from './components/app.vue';
import list from './components/list.vue';
import hello from './components/hello.vue';
//开启debug模式
Vue.config.debug = true;
// new Vue(app);//这是上一篇用到的,新建一个vue实例,现在使用vue-router就不需要了。
// 路由器需要一个根组件。
var App = Vue.extend({});
// 创建一个路由器实例
var router = new VueRouter();
// 每条路由规则应该映射到一个组件。这里的“组件”可以是一个使用 Vue.extend创建的组件构造函数,也可以是一个组件选项对象。
// 稍后我们会讲解嵌套路由
router.map({//定义路由映射
'/index':{//访问地址
name:'index',//定义路由的名字。方便使用。
component:index,//引用的组件名称,对应上面使用`import`导入的组件
//component:require("components/app.vue")//还可以直接使用这样的方式也是没问题的。不过会没有import集中引入那么直观
},
'/list': {
name:'list',
component: list
},
});
router.redirect({//定义全局的重定向规则。全局的重定向会在匹配当前路径之前执行。
'*':"/index"//重定向任意未匹配路径到/index
});
// 现在我们可以启动应用了!
// 路由器会创建一个 App 实例,并且挂载到选择符 #app 匹配的元素上。
router.start(App, '#app');