美文网首页WEB前端程序开发个人收藏web前端
『极简』一篇文章让你学会使用webpack

『极简』一篇文章让你学会使用webpack

作者: 党云龙 | 来源:发表于2019-11-26 17:21 被阅读0次

    webpack是干什么?


    我们每次开发的时候,都需要在页面的head中加载各种js资源,当你加载了jquery和vue全家桶一套以后,你会发现你的页面已经变得非常的臃肿。更别说你还需要要引用一个你自己的index.js文件。

    如果你之前接触过sea.js或者require.js的话,你就可以很容易的理解(你没接触过也无所谓)他们的核心思想就是,把所有需要引入的js,都通过一个公用的js文件去加载。并且在这个js文件中赋予一些逻辑性。

    所以最后的结果就是,你最后生成的html文件中只会引用一个js文件和一个css文件,这样不但代码变整洁了,页面打开速度也获得了巨大的提升,这就是所谓的前端优化。

    webpack就是一个为了解决这个问题而诞生的工具。当然,它绝对没有这么简单,还记得es6吗,还记得less,sass这种高科技语法吗,你直接在html中使用是不行的,因为低端浏览器并不能解析这类语法。但是通过webpack,我们可以集成一个解析器babel来帮助我们实现对这类语法的解析,让低端浏览器实现全兼容。怎么样,webpack是不是很强大?现在让我们更加详细讲解它的奥秘。

    如何安装


    webpack是基于nodejs语言的,你不会nodejs也没用关系,因为他只有几个简单的命令。

    先从nodejs的官方网站下载nodejs,安装完毕以后,打开doc窗口输入:

    npm -g i webpack@3.8.1
    

    安装完毕查看一下版本号。



    如果能正确显示版本号,说明安装成功!

    创建项目


    创建一个你想要作为项目的文件夹,然后在这个文件夹上shift+右键在弹出的菜单中选择打开powershell,这个东西是原来那个doc窗口的加强版,功能跟小黑窗一模一样。然后输入:

    npm init
    

    你会看到很多需要你输入的东西,不用管,一路回车。


    这一步的主要目的是创建一个基于npm的项目,以后,我们安装任何插件,只需要配置这个项目中的package.json文件即可。如果你之前没有使用过npm,你到这一步的时候可能会有点蒙,不要着急,我们继续往下,龙哥的文章向来就是即插即用,就算你不会安装,你把我给你的例子一拷贝,你也可以实现webpack的各种操作,原理什么的你在实战中逐渐体会也完全没问题。

    接着你用编辑软件打开刚才输入命令的那个文件夹,你会发现里面有一个package.json文件,改成我这个样子:

    {
      "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-plugin-transform-runtime": "^6.23.0",
        "babel-preset-env": "^1.6.1",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-stage-0": "^6.24.1",
        "babel-runtime": "^6.26.0",
        "autoprefixer": "^7.2.3",
        "css-loader": "^0.28.7",
        "style-loader": "^0.21.0",
        "less-loader": "^4.1.0",
        "url-loader": "^0.6.2",
        "file-loader": "^1.1.6",
        "html-webpack-plugin": "^2.30.1",
        "webpack": "^3.8.1",
        "webpack-dev-server": "^2.9.7",
        "webpack-require-http": "^0.4.3",
        "extract-text-webpack-plugin": "^3.0.2"
      },
      "name": "demo",
      "version": "1.0.0",
      "main": "webpack.js",
      "dependencies": {
        "bootstrap": "^3.3.7",
        "html-loader": "^0.5.5",
        "jquery": "^2.1.1",
        "less": "^3.0.4",
        "less-loader": "^4.1.0",
        "style-loader": "^0.21.0",
        "webpack-dev-server": "^2.11.5"
      },
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "watch": "webpack --watch",
        "dev": "webpack-dev-server"
      },
      "author": "",
      "license": "ISC",
      "description": "",
      "babel": {
        "presets": [
          "es2015",
          "react"
        ]
      }
    }
    

    刚才我们说了,这个文件主要的作用是,npm在你这个项目中,使用哪些插件。你仔细看我这个文件,里面已经包含了es6解析器,css和less,url图片地址等等各种解析器,甚至规定了webpack的版本。

    然后输入一遍

    npm install
    

    这一步操作的目的是把配置文件中的内容安装到本地。

    webpack.config.js的配置


    接着在package.json的同级目录下创建一个webpack.config.js,这个文件的目的主要是为了配置我们的webpack。

    像我这样写:

    // 引入webpack
    const webpack = require('webpack')
    // 引入html生成插件
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    // 引入css压缩插件
    const ExtractTextPlugin = require("extract-text-webpack-plugin");
    module.exports = {
        // 入口文件,指向app.js
        entry: {
            index: './src/js/index.js',
        },
        // 出口文件
        output: {
            // 项目的路径
            path: __dirname + '/dist',
            // 增加随机数防止缓存
            //filename: 'js/[name].[hash:5].js',
            // 输出的文件的路径
            filename: 'js/[name].js',
            // 为使用热启动后产生的日志文件设定输入路径
            hotUpdateChunkFilename: 'hot/hot-update.js',
            hotUpdateMainFilename: 'hot/hot-update.json'
        },
        externals:[
            // 让webpack可以加载外部http资源 例如螳螂
            require('webpack-require-http')
        ],
        // webpack-dev-server 环境
        devServer: {
            contentBase: './dist',
            hot: true
        },
        module: {
            // loader放在rules这个数组里面
            rules: [
                {
                    //把es6转换成es5
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader'
                },
                {
                    test: /\.html$/,
                    use: {
                        loader: 'html-loader'
                    }
                },
                {
                    //识别图片
                    test: /\.(png|jpg|gif)$/,
                    loader: 'url-loader',
                    options: {
                        limit: 4096,
                        name: 'image/[name].[ext]'
                    }
                },
                {    
                    //压缩css
                    test: /\.css$/,
                    use: ExtractTextPlugin.extract({
                        fallback: "style-loader",
                        publicPath: "../",
                        use: [
                            {
                                loader: 'css-loader',
                                options:{
                                    minimize: true //css压缩
                                }
                            }
                        ]
                    })
                },
                {
                    //识别字体文件
                    test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                    loader: 'file-loader?name=./fonts/[name].[ext]'
                },
            ]
        },
        // 将插件添加到webpack中
        plugins: [
            // 开启多页应用 生成html文件
            new HtmlWebpackPlugin({
                //模板文件是哪个
                template: './src/index.html',
                //选择注入哪个文件
                chunks: ['index'],
                //是否添加hash随机数防止缓存
                //hash: true,
                //开启html压缩
                minify:{
                    removeComments:true, //移除HTML中的注释
                    collapseWhitespace:true//压缩为一行
                },
                // manual根据chunks的位置手动排序
                chunksSortMode: "manual"
            }),
            // 防止webpack一直弹出警告 加载HMR需要的两个插件
            new webpack.NamedModulesPlugin(),
            new webpack.HotModuleReplacementPlugin(),
            // 解决加载jquery后 jquery不能获得$符控制权的问题
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery"
            }),
            new ExtractTextPlugin("css/styles.css"),
        ]
    }
    

    你现在肯定有点懵,这是干什么呢??上来一顿配置,我都不知道干什么呢。
    不用着急,我们先把开发环境配置好,当我们开始使用的时候,我们会逐个讲解这些配置用到的地方!

    到了这一步,你的项目文件夹下面,应该有node_modules文件夹,一个package.json文件和一个webpack.config.js文件,好的,然后你再创建两个文件夹,一个叫src,一个叫dist。

    全部完成以后是这样的:


    到了这一步,webpack的安装和配置就完成了,接下来我们该进入开发环节了。

    如何使用


    我们新建的两个目录:dist为生成生产环境,src为开发环境
    你所有的操作全部在src中完成,我们的最终目的是:
    通过小黑窗口中输入一遍webpack命令,把src中的文件压缩优化成为src文件夹中的最终形态。也就说,我们开发的时候,只需要修改src目录中的内容,正式上线的时候,只需要把dist中的文件通过ftp传到服务器就可以了。

    这里龙哥需要给你讲一下原理,现在webpack的教程有很多,但是我相信大部分人到了,入口文件那块就差不多放弃了。因为webpack它本身是基于nodejs的,nodejs顾名思义,只能编译js...

    所以,你放在项目里面的html啊,css啊甚至图片啊。nodejs一概不承认,或者你可以理解为,它不认识这是什么。

    这里我们就需要编写一个文件,让我们把项目中的所有资源都利用起来,并且告知webpack这些资源都是什么,这个文件,就叫做入口文件。这个文件的配置你可以灵活配置,我自己是选择放在src中的js文件夹中,因为这样让它们看起来更加规范一些。

    如果你仔细阅读上面的webpack.config.js文件的话,你会发现,里面的entry项就是入口文件的位置。

    然后我们来看看这个文件中都写了一些什么东西:

    //引入jquery 必须为此写法让插件和全局都获得jquery支持
    import $ from 'jquery'
    window.$ = $
    window.jQuery = $
    export default $
    //引用bootstrap
    // import 'bootstrap';
    // import 'bootstrap/dist/css/bootstrap.css';
    
    //加载自己的js
    import '../js/time/flipclock.js';
    
    //引用html加载页面上的src资源
    import '../index.html';
    
    //引入自己的css
    import '../css/index.css';
    import '../js/time/flipclock.css';
    

    你会发现,页面,页面上的css和js都是在这个js文件中被引用的。
    此时我的html页面上什么也没有引用。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>我的标题</title>
        </head>
        <body>
            <article>
                我的内容
            </article>
        </body>
    </html>
    

    你可能会好奇,如果我的html中不引入,那么最后打包完了以后,这个js文件会被加载吗?
    答案是会的,webpack会自动加载配置文件中的入口文件到你的html中。

    这里我忽然想起了一个情况:那就是,有一些时候,我们需要引入外网的资源,这些资源是不能被打包到项目中的,比如一些crm系统,或者一些站长统计的js。

    我们需要使用这个方法:

    //引入jquery 必须为此写法让插件和全局都获得jquery支持
    import $ from 'jquery'
    window.$ = $
    window.jQuery = $
    export default $
    //引用bootstrap
    // import 'bootstrap';
    // import 'bootstrap/dist/css/bootstrap.css';
    
    //加载自己的js
    import '../js/time/flipclock.js';
    
    //引用html加载页面上的src资源
    import '../index.html';
    
    //加载外网的js
    Promise.all([
        require('http://talk2.bjmantis.net/chat/js/dist/mantis.min.js?123456'),
        require('http://talk2.bjmantis.net/chat/js/dist/register_form.min.js')
    ]).then(function() {
    });
    
    //引入自己的css
    import '../css/index.css';
    import '../js/time/flipclock.css';
    

    然后让我们来完成这个页面,我添加了一些内容,然后把图片也引入了,当我们感觉编辑的差不多了的时候,在小黑窗中输入:

    npm run dev
    

    你会看到这个画面,然后打开窗口中提示的地址就能看到我们的页面。

    打包发布项目


    当我们感觉页面已经没问题可以打包上线的时候,还是在这个目录上,输入:

    webpack
    

    是的,仅仅就需要这么一个单词而已。
    然后打开dist目录,你会发现所有的文件webpack已经帮我们打包好了,然后我们把dist目录里面的文件上传到ftp就行了。

    webpack常见问题解答

    通过上面的学习,我们已经可以通过webpack压缩优化我们的项目了。
    但是我想告诉你的是webpack能做的事情远不止如此,我们经过学习,知道了webpack其实是一个打包工具,它把我们项目中用到的插件都合并成了一个js,还可以优化css和img图像。那么,我们常用的插件是哪些?它们又发挥了什么作用?打包出来的页面能否不只是一个spa而是多个页面呢?

    常用插件说明(package.json)


    package.json中有一项是devDependencies,这一项表示npm包中引用了哪些编译包

    插件名称 版本号 作用
    babel-core 6.26.0 编译es6
    babel-loader 7.1.2 编译es6
    babel-plugin-transform-runtime 6.23.0 编译es6
    babel-preset-env 1.6.1 编译es6
    babel-preset-es2015 6.24.1 编译es6
    babel-preset-stage-0 6.24.1 编译es6
    babel-runtime 6.26.0 编译es6
    autoprefixer 7.2.3 css3自动添加前缀
    css-loader 0.28.7 编译css样式表
    style-loader 0.21.0 编译css样式表
    less-loader 4.1.0 编译less样式表
    url-loader 0.6.2 编译图像,能转化为base64就转化,不能转化就通过file插入到页面中
    file-loader 1.1.6 编译图像,能转化为base64就转化,不能转化就通过file插入到页面中
    html-webpack-plugin 2.30.1 生成html 否则你的项目最后只会有一个压缩的js
    webpack 3.8.1 webpack
    webpack-dev-server 2.9.7 本地环境启动器
    webpack-parallel-uglify-plugin 1.1.0 js压缩工具
    webpack-require-http 0.4.3 加载外部文件
    extract-text-webpack-plugin 3.0.2" 提取css为一个文件

    webpack可否通过多个入口文件打包成多个页面,而不是spa


    第一步你需要HtmlWebpackPlugin
    在webpack.config中配置成这个样子,生成多个页面。

    new HtmlWebpackPlugin({
       template: './src/index.html',
       chunks: ['common', 'index']
    }),
    new HtmlWebpackPlugin({
       filename: 'list.html',
       template: './src/list.html',
       chunks: ['common', 'list']
    }),
    new HtmlWebpackPlugin({
       filename: 'detail.html',
       template: './src/detail.html',
       chunks: ['common', 'detail'] //这里是页面中允许加入哪几个js 这里你可以看到require方式的影子
    }),
    
    
    另外就是在入口文件中配置以下就行了。
    entry: {
       index: './src/js/index.js',
       list: './src/js/list.js',
       detail: './src/js/detail.js'
    },
    

    总结一下


    webpack的使用方法就为各位总结到这里啦,极简系列的文章都是龙哥总结的干货。最重要一点讲究即插即用,你完全可以复制本文中的代码到项目中,立刻对你的推广单页或者本地项目做一个优化—webpack可以做的事情远不止我本文中介绍的那些,本文只是介绍使用方法和原理,更多高级玩法还是需要你自己去开发,加油!

    相关文章

      网友评论

        本文标题:『极简』一篇文章让你学会使用webpack

        本文链接:https://www.haomeiwen.com/subject/larywctx.html