专栏名称: SegmentFault思否
SegmentFault (www.sf.gg)开发者社区,是中国年轻开发者喜爱的极客社区,我们为开发者提供最纯粹的技术交流和分享平台。
目录
相关文章推荐
程序员的那些事  ·  印度把 DeepSeek ... ·  2 天前  
程序员小灰  ·  3个令人惊艳的DeepSeek项目,诞生了! ·  2 天前  
程序猿  ·  “我真的受够了Ubuntu!” ·  3 天前  
程序员的那些事  ·  惊!小偷“零元购”后竟向 DeepSeek ... ·  3 天前  
51好读  ›  专栏  ›  SegmentFault思否

面试官:请手写一个 webpack 4.0 配置

SegmentFault思否  · 公众号  · 程序员  · 2018-07-19 08:00

正文

确认过眼神,你还是没有准备秋招的人?时间仓促。自京东6月8号开启管培生的招聘,就意味着秋招的开始。然而你还在等着秋天的到来?今年形势应该更为严峻,随着各大技术(vue,webpack,react,微信小程序)生态越来越成熟,这也意味着我们要更加深入的去了解他们,掌握他们。比如你写vue项目,知道vue-cli。写的项目也无以伦比,但是你是否又会去了解下vue-cli到底发生了什么?或许这就是面试官要问你的问题:请手写一个webpack4.0的配置。

前言

机会总是留给有准备的人,要想在这兵荒马乱的求职季里出类拔萃,拿下你心中期待已久的offer。那么你更因该知道很多别人不知道的东西,你的羽翼才能丰满,才能翱翔于天际。鹰击长空,靠的不是天生,而是年少时断崖之险。笨鸟先飞,靠的不是智慧,而是孜孜不倦的努力。

webpack详解

webpack是一个打包工具,他的宗旨是一切静态资源即可打包。有人就会问为什么要webpack?webpack是现代前端技术的基石,常规的开发方式,比如jquery,html,css静态网页开发已经落后了。现在是MVVM的时代,数据驱动界面。webpack将现代js开发中的各种新型有用的技术,集合打包。webpack的描述铺天盖地,我就不浪费大家的时间了。理解下这种图就知道webpack的生态圈了:

webpack4.0的配置

  1. const path = require('path');  //引入node的path模块

  2. const webpack = require('webpack'); //引入的webpack,使用lodash

  3. const HtmlWebpackPlugin = require('html-webpack-plugin')  //将html打包

  4. const ExtractTextPlugin = require('extract-text-webpack-plugin')     //打包的css拆分,将一部分抽离出来  

  5. const CopyWebpackPlugin = require('copy-webpack-plugin')

  6. // console.log(path.resolve(__dirname,'dist')); //物理地址拼接

  7. module.exports = {

  8.    entry: './src/index.js', //入口文件  在vue-cli main.js

  9.    output : {       //webpack如何输出

  10.        path: path.resolve(__dirname, 'dist'), //定位,输出文件的目标路径

  11.        filename: '[name].js'

  12.    },

  13.    module: {       //模块的相关配置

  14.        rules: [     //根据文件的后缀提供一个loader,解析规则

  15.            {

  16.                test: /\.js$/,  //es6 => es5

  17.                include: [

  18.                    path.resolve(__dirname, 'src')

  19.                ],

  20.                // exclude:[], 不匹配选项(优先级高于test和include)

  21.                use: 'babel-loader'

  22.             },

  23.            {

  24.                test: /\.less$/,

  25.                use: ExtractTextPlugin.extract({

  26.                    fallback: 'style-loader',

  27.                    use: [

  28.                    'css-loader',

  29.                    'less-loader'

  30.                    ]

  31.                })

  32.            },

  33.            {       //图片loader

  34.                test: /\.(png|jpg|gif)$/,

  35.                use: [

  36.                    {

  37.                        loader: 'file-loader' //根据文件地址加载文件

  38.                     }

  39.                ]

  40.            }

  41.        ]                  

  42.    },

  43.    resolve: { //解析模块的可选项  

  44.        // modules: [ ]//模块的查找目录 配置其他的css等文件

  45.        extensions: [".js", ".json", ".jsx",".less", ".css"],  //用到文件的扩展名

  46.        alias: { //模快别名列表

  47.            utils: path.resolve(__dirname,'src/utils')

  48.        }

  49.    },

  50.    plugins: [  //插进的引用, 压缩,分离美化

  51.        new ExtractTextPlugin('[name].css' ),  //[name] 默认  也可以自定义name  声明使用

  52.        new HtmlWebpackPlugin({  //将模板的头部和尾部添加css和js模板,dist 目录发布到服务器上,项目包。可以直接上线

  53.            file: 'index.html', //打造单页面运用 最后运行的不是这个

  54.            template: 'src/index.html'  //vue-cli放在跟目录下

  55.        }),

  56.        new CopyWebpackPlugin([  //src下其他的文件直接复制到dist目录下

  57.            { from:'src/assets/favicon.ico',to: 'favicon.ico' }

  58.        ]),

  59.        new webpack.ProvidePlugin({  //引用框架 jquery  lodash工具库是很多组件会复用的,省去了import

  60.            '_': 'lodash'  //引用webpack

  61.        })

  62.    ],

  63.    devServer: {  //服务于webpack-dev-server  内部封装了一个express

  64.        port: '8080',

  65.        before(app) {

  66.            app.get('/api/test.json', (req, res) => {

  67.                res.json({

  68.                    code: 200,

  69.                    message: 'Hello World'

  70.                })

  71.            })

  72.        }

  73.    }

  74. }

一、前端环境搭建

我们使用npm或yarn来安装webpack。

  1. npm install webpack webpack-cli -g

  2. # 或者

  3. yarn global add webpack webpack-cli

为什么webpack会分为两个文件呢?在webpack3中,webpack本身和它的cli以前都是在同一个包中,但在第4版中,他们已经将两者分开来更好地管理它们。

新建一个webpack的文件夹,在其下新建一个try-webpack(防止init时项目名和安装包同名)并初始化和配置webpack。

  1. npm init -y  //-y 默认所有的配置

  2. yarn add webpack webpack-cli -D  //-D webpack安装在devDependencies环境中

二、部署webpack

在上面搭建好的环境项目中,我们来到package.json里配置我们的scripts。

  1.  "scripts": {

  2.    "build": "webpack --mode production" //我们在这里配置,就可以使用npm run build 启动我们的webpack

  3.  },

  4.  "devDependencies": {

  5.    "webpack": "^4.16.0",

  6.    "webpack-cli": "^3.0.8"

  7.  }

配置好我们webpack的运行环境时,联想下vue-cli。平时使用vue-cli会自动帮我们配置并生成项目。我们在src下进行项目的开发,最后npm run build 打包生成我们的dist的目录。不知道你是否还记得,还是让我们进入下一节让我们感受下这其中的正个流程吧。

三、npm run build 发生了什么

在我们的根项目下try-webpack新建一个src目录。在src目录下新建一个index.js文件。在里面我们可以写任意的代码,以案例为主:

  1. const a = 1;

写完之后我们在终端运行我们的命令: npm run build ,你就会发现新增了一个dist目录,里面存放着webpack打包好的main.js文件。这和我们在vue-cli里操作是一样的。

四、webpackp配置流程篇

我们在开发是一般会打包src下的什么文件呢?我们可以回忆一下,其实vue-cli项目src下不就这几点嘛:

  • 发布时需要的html,css,js

  • css预编译器stylus,less,sass

  • es6的高级语法

  • 图片资源.png,.gif,.ico,.jpg

  • 文件间的require

  • 别名@等修饰符

那么我将会分这几点来讲解webpack中webpack.config.js的配置,跟着脚步,一步一步的来完成我们的流程线。

✍️Html在webpack中的配置

在项目的根目录try-webpack下新建webpack.config.js文件,以commonJS模块化机制向外输出,并且新建一个index.html。

  1. module.exports = {}

配置我们的入口entry,在vue-cli里相当于跟目录下的main.js,我们的出口output。我们可以把webpack理解为一个工厂,进入相当于把各种各样的原料放进我们的工厂了,然后工厂进行一系列的打包操作把打包好的东西,向外输出,然后就可以去出售了(上线)。

  1. const path = require('path'); //引入我们的node模块里的path

  2. //测试下 console.log(path.resolve(__dirname,'dist')); //物理地址拼接

  3. module.exports = {

  4.    entry: './src/index.js', //入口文件  在vue-cli main.js

  5.    output: {       //webpack如何向外输出

  6.        path: path.resolve(__dirname, 'dist'),//定位,输出文件的目标路径

  7.        filename: '[name].js' //文件名[name].js默认,也可自行配置

  8.    },

HTML打包我们需要安装引入html-webpack-plugin

  1. yarn add html-webpack-plugin - D //在开发环境中安装

  2. const HtmlWebpackPlugin = require('html-webpack-plugin')  //引入打包我们的HTML

在module.exports里配置我们的plugins(插件):

  1. plugins: [  //插进的引用, 压缩,分离美化

  2.        new HtmlWebpackPlugin({  //将模板的头部和尾部添加css和js模板,dist 目录发布到服务器上,项目包。可以直接上线

  3.            file: 'index.html', //打造单页面运用 最后运行的不是这个

  4.            template: 'src/index.html'  //vue-cli放在跟目录下

  5.        }),

  6.    ],

配置好后,在终端输入npm run dev后webpack将我们的html打包好并且自动将我们的js引进来了。

  1.    

    class="main">Hello World

live-sever我们的dist目录,启动一个8080端口,我们就可以看到我们的Hello World了。这就是我们上线版的页面。

🍉css在webpack中的配置

在我们vue-cli里,我们可以使用css去写我们的样式,也可以使用高级stylus,less,sass等预编译器。这里就以less为例,看看webpack怎么将他打包成一个css。

  1. .main {

  2.  color: red;

  3. }

在src目录下新建我们的style.less文件,在配置之前我们需要npm我们的css-loader和sass-loader,sass:

yarn add css - loader less less - loader style - loader - D

执行完上述命令我们在packge.json里可以看到我们的配置文件:

  1. "devDependencies": {

  2.    "css-loader": "^1.0.0",

  3.    "html-webpack-plugin": "^3.2.0",

  4.    "sass": "^1.9.0",

  5.    "sass-loader": "^7.0.3",

  6.    "webpack": "^4.16.0",

  7.    "webpack-cli": "^3.0.8"

  8.   }

安装好后,我们开始配置webpack.config.js文件。这里申明一下,我们的css在dist目录下需要和我们的HTML分离,这是还需引入我们的extract-text-webpack-plugin,先然我们安装下:

yarn add extract - text - webpack - plugin - D

这里有一个坑,extract-text-webpack-plugin在4.0并不支持这样的安装,大家可自行chrome。于是我们选择换一种方式,选择4.00-beta.0版本的:

yarn add extract - text - webpack - plugin@last - D

来到我们的module.exports里,完成moudel的配置:

  1.  const ExtractTextPlugin = require('extract-text-webpack-plugin')     //打包的css拆分,将一部分抽离出来  

  2.   module: {       //模块的相关配置

  3.        rules: [     //根据文件的后缀提供一个loader,解析规则

  4.            {

  5.                test: /\.less$/, //正则匹配我们以.less结尾的文件

  6.                use: ExtractTextPlugin.extract({

  7.                    fallback: 'style-loader',

  8.                    use: [

  9.                    'css-loader',

  10.                    'less-loader'

  11.                    ]

  12.                })

  13.            },

  14.        ]},

  15.     plugins:[

  16.        new ExtractTextPlugin('[name].css'),  //[name] 默认  也可以自定义name  声明使用

  17.     ]

我们在执行我们的 npm run build 之后并没有我们的css,为什么呢?原来在webpack配置里css in js。意思是在打包是我们的css是打包在我们的js里的,所有我们引入了extract-text-webpack-plugin插件将css从里面剥离出来。不过又一个问题,require的机制?

在我们打包过程中,文件的引用require 按照顺序来打包,这就是文件依赖的机制。

打包好后我们在live-server,发现我们的样式也上去了,并且css部分分离出来了。

🍊js在webpack中的配置

现在随着es6的普及,越来越多的代码使用es6了,但是很多浏览器并不支持es6,比如async/awiat,const。因此需要我们引用babe来把我们es6的代码编译为es5。在跟目录下新建.babelrc,简单配置下:







请到「今天看啥」查看全文