前端构建工具之“Webpack”

  • 编辑时间: 2016-08-28
  • 浏览量: loading
  • 作者: 段亮

前言:还记得刚接触前端的时候,对于“前端构建工具”这个词一脸茫然。并不知道使用它,能为我们做些什么事情。以及它能帮我们,解决什么样的问题?

下面就跟大家一起来学习下:目前比较火的前端构建工具“Webpack”

一、什么是Webpack

Webpak在官方的定义是:MODULE BUNDLER 译为(模块加载器),它的目的就是把有依赖关系的各种文件,打包成一系列的静态资源。请看下图

webpack


其实webpack的出来,主要是为了更好的适配大型单页面应用程序开发(SPA)。(不懂什么是单页面应用程序开发的同学,就请自行百度吧!)

为什么这么说呢?

因为webpack可以使其代码分离,按需加载。以及静态资源模块化无缝结合。

webpack简单点来说就是一个配置文件,所有的黑魔法都是在这一个文件中发生的。 这个配置文件主要可以分为以下几个模块:


1、entry(入口文件) 


入口文件


它会让webpack知道用哪个文件作为项目的入口。


2、output(出口) 


output


通过它,可以让webpack把处理完成的文件放在什么地方。


3、module(模块) 


module


模块加载是webpack的最强大之处。为什么这么说呢?因为你需要引用什么文件,直接配置好相关的loader就行。(一切皆为模块)

比如 :我们在项目中需要引用.json文件,只需配置一个json-loader即可。引用相关的jquery插件,配置一个imports-loader即可...然后在页面中可以通过require方式 或者 ES6语法import直接引入就好。

是不是很强大呢?在webpack中一切皆Module模块。这就是我们之前所说的,模块加载器就是这样的原因。


4、plugins 插件

webpack丰富的插件系统。


plugins


比如:html模板,CSS行内样式提取器,热加载....

当然webpack的配置不仅仅只有我说这几项。还有很多...


二、webpack能帮我们做什么?

  1、代码分割,按需加载。

  2、图片自动转成base64。

  3、自动打包编译压缩混淆,添加md5..


如果我们要使用Vue.js来搭建一个SPA单页。那么可能你的Webpack配置如下:

var webpack = require("webpack");
var path = require('path');// NodeJS中的Path对象,用于处理目录的对象,提高开发效率。
var HtmlWebpackPlugin = require('html-webpack-plugin');//webpack html模板插件
var ExtractTextPlugin = require("extract-text-webpack-plugin"); //css提取插件
var CopyWebpackPlugin = require('copy-webpack-plugin');//复制文件
var CleanPlugin = require('clean-webpack-plugin')//webpack插件,用于清除目录文件
var production = process.env.NODE_ENV;
module.exports = {
    // 入口文件地址
    entry:{
        index : ['./src/main.js']
    },
    // 输出
    output: {
        path: path.resolve(__dirname, './dist'), //入口文件的输出地址
        filename: production ? 'js/[name].[hash:8].js' : '[name].js',
        //[name]这里是webpack提供的根据路口文件自动生成的名字
        publicPath: ""//静态资源在server服务上和打包输出的地址
    },
    resolve: {
         //设置require或import的时候可以不需要带后缀
        extensions: ['', '.js', '.vue', '.scss', '.less', '.css']
    },
    // 服务器配置相关,自动刷新!
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        port: 8010//端口
        //contentBase: path.join(__dirname, '/dist/view/')//配置网站根目录
    },
    // 加载器
    module: {
        // 加载器
        loaders: [
            {
                test: /\.vue$/,
                loader: 'vue'
            },
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract("style","css")
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract("style-loader", "css!sass")
            },
            {
                test: /\.js$/,
                loader: 'babel',
                exclude: /node_modules/
            },
            {
                test: /\.json$/,
                loader: 'json'
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'file',
                query: {
                    limit: 8000,
                    name: '../images/[name].[ext]?[hash:4]'
                }
            },
            {
                test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'file-loader?name=./fonts/[name].[ext]'
            }
        ]
    },
    vue: {
        loaders: {
            css: 'style!css!autoprefixer',
        }
    },
    // 转化成es5的语法
    babel: {
        presets: ['es2015'],
        plugins: ['transform-runtime']
    },
    plugins: [
        new webpack.ProvidePlugin({ //全局配置加载
           "$": "jquery",
           "jQuery": "jquery",
           "window.jQuery": "jquery"
        }),
        new CleanPlugin(['dist']),
        new ExtractTextPlugin(production ? "./css/[name].[hash:8].css" : "./css/[name].css"),
        //单独使用link标签加载css并设置路径,相对于output配置中的publickPath
        new HtmlWebpackPlugin({
            title: 'vue-webpack-test',
            //favicon: './src/img/favicon.ico', //favicon路径,通过webpack引入同时可以生成hash值
            filename: './index.html', //生成的html存放路径,相对于path
            template: './src/view/index.html', //html模板路径
            inject: true, //允许插件修改哪些内容,包括head与body
            //hash: true, //为静态资源生成hash值
            cache:false,//是否缓存
            //chunks: ['main'],//需要引入的chunk,不配置就会引入所有页面的资源
            minify: { //压缩HTML文件
                removeComments: true, //移除HTML中的注释
                collapseWhitespace: false //删除空白符与换行符
            }
        }),
        new webpack.HotModuleReplacementPlugin(),//热加载
        new webpack.optimize.OccurenceOrderPlugin(),
        //复制文件,输出路径相对应path
        new CopyWebpackPlugin([
            {from: 'src/images', to: '/images'},
            {from: 'src/css', to: '/css'}
        ])
    ],
    //添加了此项,则表明从外部引入,内部不会打包合并进去
    externals: {
        jquery: 'window.jQuery'
    },
    // 开启source-map,webpack有多种source-map,在官网文档可以查到
    devtool: '#eval-source-map'
};
//判断为生产模式,压缩js
if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurenceOrderPlugin()
  ])
}

   可能会在后续文章,我会讲解怎么使用webpack来搭建SPA单页应用,以及多页面开发。以上代码只作为参考!


go


写在最后:可能很多朋友认为,现在的前端变得越来越难学了。因为需要学习各种前端MVVM框架的(react、angular、vue)、es6语法、前端构建工具、node.js...才能驾驭项目。但是我感觉用“难”这个词来形容它,觉得有点不恰当。反而觉得前端慢慢的趋向于工程化,从最开始的编码,到测试、上线等一整套流程。

如果你不想继续做个切图仔”,那你还有什么理由不来学习呢?

以上观点纯属段亮个人观点与见解,如有不足之处。还望指出!

本文出自段亮个人博客,如需转载请注明出处。

本文出处:http://www.duanliang920.com/learn/web351.html

如果您觉得文章对你有帮助,可以进行打赏。
打赏多少,您高兴就行,谢谢您对段亮这小子的支持! ~(@^_^@)~

微信扫一扫 微信打赏

支付宝扫一扫 支付宝打赏

你也想建立一个独立博客?

你是否也想打造一个在互联网上的个人品牌,成为一个家喻户晓的人物呢?
请点击了解 怎样创建个人博客