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');

[参考链接]