主页»JavaScript»还学不会webpack?看这篇!

还学不会webpack?看这篇!

来历:MudOnTire 发布时刻:2019-05-29 阅览次数:

  Webpack现已盛行好久了,但许多同学运用webpack时仍是一头雾水,一下看到那么多文档、各种装备、各种loader、plugin立马就晕头转向了。我也不破例,以至于很长一段时刻对webpack都是一知半解的状况。可是想要持续做好前端,webpack是必须得跨过的一道坎,其实把握webpack并不难,仅仅咱们没有找到正确的办法。本文便是我自己在学习webpack时的一点心得体会,供咱们参阅。

 什么是webpack?

  一句话归纳:webpack是一个模块打包东西(module bundler)。要点在于两个要害词“模块”和“打包”。什么是模块呢?咱们回忆一下从前的前端开发办法,js文件经过script标签静态引进,js文件之间因为没有强依靠联系,假如文件1要用到文件2的某些办法或变量,则必须将文件1放到文件2后边加载。跟着项目的增大,js文件之间的依靠联系越发扑朔迷离,保护难度也越来越高。这样的窘境唆使着前端工程师们不断探究新的开发形式,从后端、app的开发形式中咱们取得创意,为什么不能引进“模块”的概念让js文件之间能够彼此引证呢?模块1要运用模块2的功用,只需求在该模块1中清晰引证模块2就行了,而不必忧虑它们的摆放次序。依据这种理念,CommonJSAMD标准被发明了出来,然后有了require.js、system.js这样的前端模块加载东西和node的模块体系,直到现在盛行的es6 module

  模块的引进处理了文件之间依靠引证的问题,而打包则处理了文件过多的问题。当项目规划增大,模块的数量数以千计,浏览器假如要加载如此多的文件,页面加载的速度势必会受影响,而bundler能够把多个相关的文件打包到一同然后许多削减文件的数量进步网页加载功用。供给模块化的开发办法和编译打包功用便是webpack的中心,其他许多功用都环绕它们打开。

 中心概念

  Module(模块)

  关于webpack,模块不仅仅是javascript模块,它包含了任何类型的源文件,不管是图片、字体、json文件都是一个个模块。Webpack支撑以下的办法引证模块:

  Dependency Graph(依靠联系图)

  所谓的依靠联系图是webpack依据每个模块之间的依靠联系递归生成的一张内部逻辑图,有了这张依靠联系图,webpack就能按图索骥把一切需求模块打包成一个bundle文件了。

  Entry(进口)

  制作依靠联系图的开始文件被称为entry。默许的entry为 ./src/index.js,或许咱们能够在装备文件中装备。entry能够为一个也能够为多个。

  单个entry:

module.exports = {
  entry: './src/index.js'
}

或许

module.exports = {
  entry: {
    main: './src/index.js'
  }
};

  多个entry,一个chunk

  咱们也能够指定多个独立的文件为entry,但将它们打包到一个chunk中,此种办法被称为 multi-main entry,咱们需求传入文件途径的数组:

module.exports = {
  entry: ['./src/index.js', './src/index2.js', './src/index3.js']
}

  可是改种办法的灵活性和扩展性有限,因而并不引荐运用。

  多个entry,多个chunk

  假如有多个entry,而且每个entry生成对应的chunk,咱们需求传入object:

module.exports = {
  entry: {
    app: './src/app.js',
    admin: './src/admin.js'
  }
};

  这种写法有最好的灵活性和扩展性,支撑和其他的部分装备(partial configuration)进行兼并。比方将开发环境和出产的装备别离,并抽离出公共的装备,在不同的环境下运转时再将环境装备和公共装备进行兼并。

  Output(出口)

  有了进口,对应的就有出口。望文生义,出口便是webpack打包完结的输出,output界说了输出的途径和文件称号。Webpack的默许的输出途径为 ./dist/main.js。相同,咱们能够在装备文件中装备output:

module.exports = {
  entry: './src/index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js'
  }
};

  多个entry的状况

  当有多个entry的时分,一个entry应该对应一个output,此刻输出的文件名需求运用替换符(substitutions)声明以保证文件名的唯一性,例如运用进口模块的称号:

module.exports = {
  entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }
}

  终究在 ./dist 途径下面会生成 app.js和search.js两个bundle文件。

  Loader(加载器)

  Webpack本身只支撑加载js和json模块,而webpack的理念是让一切的文件都能被引证和加载并生成依靠联系图,所以loader进场了。Loader能让webpack能够去处理其他类型的文件(比方图片、字体文件、xml)。咱们能够在装备文件中这样界说一个loader:

  webpack.config.js

module.exports = {
  module: {
    rules: [
      { 
        test: /\.txt$/, 
        use: 'raw-loader' 
      }
    ]
  }
};

  其间test界说了需求被转化的文件或许文件类型,use界说了对该文件进行转化的loader的类型。该条装备相当于告知webpack当遇到一个txt文件的引证时(运用require或许import进行引证),先用raw-loader转化一下该文件再把它打包进bundle。

  还有其他各种类型的loader,比方加载css文件的css-loader,加载图片和字体文件的file-loader,加载html文件的html-loader,将最新JS语法转化成ES5的babel-loader等等。完好列表请参阅 webpack loaders

  Plugin(插件)

  Plugin和loader是两个比较混杂和含糊的概念。Loader是用来转化和加载特定类型的文件,所以loader的履行层面是单个的源文件。而plugin能够完成的功用更强壮,plugin能够监听webpack处理进程中的要害事情,深度集成进webpack的编译器,能够说plugin的履行层面是整个构建进程。Plugin体系是构成webpack的骨干,webpack本身也依据plugin体系建立,webpack有丰厚的内置插件和外部插件,而且答运用户自界说插件。官方列出的插件有 这些

  与loader不同,运用plugin咱们必须先引证该插件,例如:

const webpack = require('webpack'); // 用于引证webpack内置插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 外部插件

module.exports = {
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

 实践

  了解webpack的基本概念之后,咱们经过实践来加深了解。接下来,咱们运用webpack建立一个简易的react脚手架。

  创立项目

  首要创立react-webpack-starter项目并运用 npm init 初始化。

  装置依靠

  装置react

npm i react react-dom

  装置webpack相关

npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin style-loader css-loader

  装置webpack-cli后能够在指令行中履行webpack指令;webpack-dev-server供给了简易的web服务器,而且在修正文件之后主动履行webpack的编译操作并主动改写浏览器,省去了重复的手动操作;html-webpack-plugin用于主动生成index.html文件,而且在index.html中主动添加对bundle文件的引证;style-loader和css-loader用于加载css文件。

  装置babel相关

  因为react中运用了class, import这样的es6的语法,为了进步网站的浏览器兼容性,咱们需求用babel转化一下。

npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader 

  其间@babel/core是babel的中心模块,包含了babel的中心功用;@babel/preset-env支撑转化ES6以及更新的js语法,而且可依据需求兼容的浏览器类型挑选加载的plugin然后精简生成的代码;@babel/preset-react包含了babel转化react所需求的plugin;babel-loader是webpack的babel加载器。

  装备webpack

  在项目根目录下面新建webpack.config.js,内容如下:

  webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_module/,
        use: 'babel-loader'
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'] // 留意摆放次序,履行次序与摆放次序相反
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
}

  其间HtmlWebpackPlugin运用自界说的模版来生成html 文件,模版的内容如下:

  ./src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>My React App</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

  装备babel

  在项目根目录下面新建.babelrc文件,装备咱们装置的两个babel preset:

  .babelrc

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

  生成react运用根节点

  ./src/index

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';

ReactDOM.render(<App />, document.getElementById('app'));

  ./src/component/App.js

import React, { Component } from 'react';
import './App.css';

export default class App extends Component {
  render() {
    return (
      <div>
        my react webpack starter
      </div>
    )
  }
}

  ./src/components/App.css

body{
  font-size: 60px;
  font-weight: bolder;
  color: red;
  text-transform: uppercase;
}

  装备 package.json

  最终,在package.json文件里边加上两个scripts,用来运转开发服务器和打包:

  package.json

"scripts": {
  "start": "webpack-dev-server --mode development --open --hot",
  "build": "webpack --mode production"
}

  留意,咱们启用了webpack-dev-server的模块热更新功用(HMR),进一步进步咱们的开发功率。

  到此一个最简版别的react脚手架就建立完结了,咱们运转一下看看作用:

  是不是没有幻想中的那么难呢?当然webpack还有许多其他的功用和特性需求把握,期望在参阅本文之后咱们进一步的学习愈加顺畅 😊。

  本文demo地址:https://github.com/MudOnTire/...

QQ群:凯发娱乐官网官方群(515171538),验证音讯:10000
微信群:加小编微信 849023636 邀请您参加,验证音讯:10000
提示:更多精彩内容重视微信大众号:全栈开发者中心(fsder-com)
网友谈论(共0条谈论) 正在载入谈论......
沉着谈论文明上网,回绝歹意咒骂 宣布谈论 / 共0条谈论
登录会员中心