webpack系统配置

简言之,webpack 是一个模块打包器 (module bundler),可以将任何资源如 JavaScript 文件、CSS 文件、图片等打包成一个或少数文件。javascript

为何要用Webpack?css

首先,定义已经说明了 webpack 能将多个资源模块打包成一个或少数文件,这意味着与以往的发起多个 HTTP 请求来得到资源相比,如今只须要发起少许的 HTTP 请求。html

其次,webpack 能将你的资源转换为最适合浏览器的“格式”,提高应用性能。好比只引用被应用使用的资源 (剔除未被使用的代码),懒加载资源 (只在须要的时候才加载相应的资源)。再次,对于开发阶段,webpack 也提供了实时加载和热加载的功能,大大地节省了开发时间。除此以外,还有许多优秀之处之处值得去挖掘。不过,webpack 最核心的仍是打包的功能。前端

webpack,gulp/grunt,npm,它们有什么区别?html5

webpack 是模块打包器(module bundler),把全部的模块打包成一个或少许文件,使你只需加载少许文件便可运行整个应用,而无需像以前那样加载大量的图片,css文件,js文件,字体文件等等。而gulp/grunt 是自动化构建工具,或者叫任务运行器(task runner),是把你全部重复的手动操做让代码来作,例如压缩JS代码、CSS代码,代码检查、代码编译等等,自动化构建工具并不能把全部模块打包到一块儿,也不能构建不一样模块之间的依赖图。二者来比较的话,gulp/grunt 没法作模块打包的事,webpack 虽然有 loader 和 plugin能够作一部分 gulp/grunt 能作的事,可是终究 webpack 的插件仍是不如 gulp/grunt 的插件丰富,能作的事比较有限。因而有人二者结合着用,将 webpack 放到 gulp/grunt 中用。然而,更好的方法是用 npm scripts 取代 gulp/grunt,npm 是 node 的包管理器 (node package manager),用于管理 node 的第三方软件包,npm 对于任务命令的良好支持让你最终省却了编写任务代码的必要,取而代之的,是老祖宗的几个命令行,仅靠几句命令行就足以完成你的模块打包和自动化构建的全部需求。java

首先看下webpack最基本的应用:node

全局使用react

一、全局安装webpack:jquery

cnpm install webpack -g

二、建立项目:webpack

mkdir app

在 app 目录下添加 runoob1.js 文件,代码以下:

document.write("It works.");

在 app 目录下添加 index.html 文件,代码以下:

<html>
    <head> <meta charset="utf-8"> </head> <body> <script type="text/javascript" src="bundle.js" charset="utf-8"></script> </body> </html>

接下来咱们使用 webpack 命令来打包:

webpack runoob1.js bundle.js

执行以上命令会编译 runoob1.js 文件并生成bundle.js 文件,成功后输出信息以下所示:

Hash: a41c6217554e666594cb
Version: webpack 1.12.13
Time: 50ms
    Asset     Size  Chunks             Chunk Names
bundle.js  1.42 kB       0  [emitted]  main
   [0] ./runoob1.js 29 bytes {0} [built]

在浏览器中打开 index.html,输出结果以下:

webpack的使用,最复杂的一部分是莫过于它的配置项。webpack经过你的配置项,放置全部与打包相关的信息。一个基本的配置包括:

module.exports = { entry: '', output: {}, module: { rules: [] }, plugins: [], };

你若是要打包一个文件,那首先要指定文件的地址,也就是entry;打包以后放在那里呢,也就是output;打包过程当中文件要通过怎么样的处理,也就是rules中的loader;如何可以使webpack打包更快,体积更小呢,也就是plugins。这些配置相辅相成,紧密结合。

安装到本项目:

npm i -D // npm install --save-dev的简写,是指安装模块并保存到package.json的devDependencies
npm i webpack -D //安装最新的稳定版本
npm i webpack@<version> -D // 安装指定版本
npm i webpack@beta -D // 安装最新的体验版本

安装完成后能够经过如下途径运行安装到本项目的webpack:

一、根项目目录下对应的命令行里经过".\node_modules\.bin\webpack"(注意:不是"./node_modules/.bin/webpack")运行webpack的可执行文件。 

二、在npm script里定义的任务会优先使用本项目下的webpack,代码以下:

"scripts": { "start": "webpack --config webpack.config.js" }

虽然介绍了以上两种安装方式, 可是咱们推荐安装到本项目,缘由是可防止不一样的项目因依赖不一样版本的webpack而致使冲突。

模块化:

一、Common.js:

// 导出 function moduleA(){ ... } module.exports = moduleA; // 导入 const moduleA = require("./moduleA "); 

CommonJS的优势在于:

a、代码可复用于Node.js环境下并运行,例如作同构应用;

b、经过NPM发布的不少第三方模块都采用了CommonJS规范。

CommonJS的缺点:

这样的代码没法直接运行在浏览器环境下,必须经过工做转换成标准的ES5。

二、AMD:

与CommonJS最大的不一样是采用了异步的方式去加载依赖的模块。

采用AMD导入导出的代码以下:

// 定义一个模块: define("module", ["dep"], function(dep){ return exports; }); // 导入 require("module", function(module){ })

AMD的优势:

a、可在不转换代码的状况下直接在浏览器中运行;

b、可异步加载依赖;

c、可并行加载多个依赖;

d、代码可运行在浏览器环境和Node.js环境下。

缺点:

JavaScript运行环境没有原生支持AMD,须要先导入实现了AMD的库后才能正常使用。

三、es6模块化:

ES6 模块化是国际标准化组织 ECMA 提出的 JavaScript 模块化规范,它在语言层面上实现了模块化。浏览器厂商和 Node.js都宣布要原生支持该规范 。 它将逐渐取代 CommonJS 和AMD 规范,成为浏览器和服务器通用的模块解决方案 。

采用 ES6 模块化导入及导出的代码以下:

//导入
import { readFile } from ’ fs ’; import React from ’ react ’ ; //导出 export function hello {) { }; export default { // ... }; 

ES6 模块虽然是终极模块化方案,但它的缺点在于目前没法直接运行在大部分 JavaScript运行环境下,必须经过工具转换成标准的 ES5 后才能正常运行。 

4. 样式文件申的模块化:

除了 JavaScript 开始进行模块化改造,前端开发里的样式文件也支持模块化。以 scss 为例,将一些经常使用的样式片断放进一个通用的文件里,再在另 一个文件里经过@ import 语句导入和使用这些样式片断 :
// util.scss 文件

// util.scss 文件

// 定义样式片断
@mixin center {
    //水平坚直居中
    position: absolute;
    left: 50%;
    top : 50%;
    transform : translate(-50%,-50%);
}

// main.scss 文件

// 导入和使用 util.scss 中定义的样式片断
@import "util";
#box{
    @include center ;
}

webpack版本不一样,使用方式可能也会不一样,下面来看下webpack3的使用:

1、webpack3的使用:

普通打包:

一、首先,建立一个目录,好比test11,使用npm初始化目录:

npm init

执行后会有一系列选项,能够按回车键快速确认,完成后会在test11目录生成一个package.json的文件。

二、以后在本机局部安装webpack:

npm install webpack@3.10.0 --save-dev

--save-dev会作为开发依赖来安装webpack。安装成功后,在package.json中会多了一项配置:

"devDependencies" : { "webpack": "^3.10.0", }

此时的package.json文件为:

{
  "name": "test11", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^3.10.0" } } 

看到"devDependencies"中含有webpack,就说明已经安装成功了,很快就能够启动一个webpack工程。

接下来新建一个src目录而且在src目录下新建main.js文件:

console.log("hello webpack");

新建一个index.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./dist/bundle.js"></script>
</head>
<body>

</body>
</html>

如今的文件夹目录结构以下:

执行如下命令打包main.js:

webpack src/main.js dist/bundle.js

若是有webpack.config.js文件,则直接输入“webpack”命令便可打包:

webpack

其中webpack.config.js配置以下:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模块 module.exports={ entry: { entry: './src/main.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路劲(获取绝对路径) filename: 'bundle.js' // 打包文件 }, module: {}, plugins: [], devServer: {}, }

出现以下信息说明打包成功:

经过npm run build命令打包:

修改package.json中的script命令:

"build": "webpack src/main.js dist/bundle.js"
{
  "name": "test11", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack src/main.js dist/bundle.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.4", "webpack": "^3.10.0" } }

 而后命令行输入:

npm run build

一样也能够打包。

 实现自动监听:

修改package.json文件中的script命令:

"watch": "npm run build -- --watch"
{
  "name": "test11", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack src/main.js dist/bundle.js", "watch": "npm run build -- --watch" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.4", "webpack": "^3.10.0" } } 

命令行输入:npm run watch  打包。

 2、webpack4的使用:

一、首先,建立一个目录,好比demo,使用npm初始化目录:

npm init

执行后会有一系列选项,能够按回车键快速确认,完成后会在demo目录生成一个package.json的文件。

二、以后在本机局部安装webpack:

npm install webpack --save-dev

--save-dev会作为开发依赖来安装webpack。安装成功后,在package.json中会多了一项配置:

"devDependencies" : {

 "webpack": "^4.16.3",

}

此外还需安装webpack-cli:

npm install webpack-cli --save-dev

三、配置webpack:

建立 webpack.config.js 文件做为webpack的配置文件。

var path = require('path');

var config = {
    entry: {
        main: './main'//配置的单入口,webpack会从main.js开始工做
    },
    output: {
        path: path.join(__dirname, './dist'),//存放打包后文件的输出目录
        publicPath: '/dist/',//指定资源文件的引用目录,
        filename: 'bundle.js'//指定输出文件的名称,只要在html中引用它便可

    }
};

module.exports = config;

新建index.html文件:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> </head> <body> <div id='root'></div> <script type="text/javascript" src="./dist/bundle.js" charset="utf-8"></script> </body> </html>

新建main.js文件:

document.write("test webpack4.0");

如今工程目录结构为:

四、使用webpack:

设置开发或者生产模式:

在 webpack.config.js 里设置

mode: 'development'

为了方便使用,咱们在package.json里加入webpack打包的命令方便咱们使用修改script项 :

"scripts": { "build": "npx webpack --config webpack.config.js" },

这样再次运行咱们直接输入:

npm run build

就能够了。

2、webpack.config.js:

归根结底,webpack就是一个.js配置文件,咱们创建一个webpack.config.js文件,咱们能够在其中进行各项配置。

好比咱们想要使用一个热加载网页的框架webpack-dev-server(webpack-dev-server是一个轻量级的服务器,修改文件源码后,自动刷新页面将修改同步到页面上),咱们先安装:

npm install webpack@4.6.0 webpack@2.0.15 webpack-dev-server@3.1.3 --save-dev

而后在package.json的"scripts"里增长一个快速启动webpack-dev-server服务的脚本:

"scripts": { "dev": "webpack-dev-server --open --config webpack.config.js" },

 package.json的详细配置以下:

{
  "name": "test13", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "dev": "webpack-dev-server --open --config webpack.config.js" }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.6.0", "webpack-cli": "^2.0.15", "webpack-dev-server": "^3.1.3" } }

在webpack.config.js中对webpack.config.js中添加devServer选项对webpack-dev-server进行详细配置:

devServer:{
        port: 3000,
        publicPath: "./"
    }

 webpack.config.js的详细配置以下:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模块 module.exports={ entry: { entry: './src/main.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路劲(获取绝对路径) filename: 'bundle.js' // 打包文件 }, module: {}, plugins: [], devServer: { open: true, port: 8080 } }

当运行:

npm run dev

命令时,就会执行

webpack-dev-server --open --config webpack.config.js

其中--config是指向webpac-dev-server读取的配置文件路径,这里直接读取咱们在上一步建立的webpack.config.js文件。

--open会在执行命令时自动在浏览器中打开页面,默认地址是127.0.0.1:8080,不过ip和端口都是能够配的:

webpack配置中最重要的也是必选的两项是入口和出口,入口的做用是告诉webpack从哪里开始寻找依赖,而且编译。出口则用来配置编译后的文件存储位置和文件名。

在终端执行

npm run dev

就会自动在浏览器中打开页面了。

3、完善配置文件:

在webpack的世界里,每个文件都是一个模块,好比.css,.js,.html,.jpg,.less等。对于不一样的模块,须要用不一样的加载器来处理,而加载器就是webpack最重要的功能。经过安装不一样的加载器能够对各类不一样后缀名的文件进行处理,好比如今要写一个css样式,就要用到css-loader和style-loader。用npm方式安装它:

npm install css-loader --save-dev
npm install style-loader --save-dev

安装完成后,在webpack.config.js文件里配置Loader,增长对.css文件的处理:

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
                'style-loader',
                'css-loader'
            ]
      }
    ]
  }

webpack看似复杂,但它不过是一个js配置文件,只要搞清楚入口、出口、加载器、插件这四个概念,使用起来就不那么困惑了。

4、Loaders

Loaders是webpack提供的最激动人心的功能之一了。经过使用不一样的loader,webpack有能力调用外部的脚本或工具,实现对不一样格式的文件的处理,好比说分析转换scss为css,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件,对React的开发而言,合适的Loaders能够把React的中用到的JSX文件转换为JS文件。

Loaders须要单独安装而且须要在webpack.config.js中的modules关键字下进行配置,Loaders的配置包括如下几方面:

test:一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)

loader:loader的名称(必须)

include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不须要处理的文件(文件夹)(可选);
query:为loaders提供额外的设置选项(可选)

下面以css的处理为例来讲明:

一、以es6方式导入文件:

如今写一些css,就须要用到style-loader和css-loader,如今经过npm来安装:

npm install css-loader style-loader --save-dev

安装完成后,创建一个css文件:

body { background: pink; }

在main.js文件中增长以下代码:

import css from './app.css'; console.log("hello world");

从新执行: 

npm run build

文件夹结构以下:

其中,app.css:

body { background: pink; }

app.js:

import css from './app.css'; console.log("hello world");

 index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./dist/bundle.js"></script> </head> <body> </body> </html>

package.json:

{
  "name": "test16", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "style-loader": "^0.23.1", "webpack": "^3.6.0" } } 

 webpack.config.js:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模块 module.exports={ entry: { entry: './src/app.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路劲(获取绝对路径) filename: 'bundle.js' // 打包文件 }, module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] } ] }, plugins: [], devServer: {}, }

二、以commonJS方式导入文件:

文件目录:

package.json:

{
  "name": "test25", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --config webpack.config.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "style-loader": "^0.23.1", "webpack": "^3.6.0" } } 

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

 show.js:

function show(content){ document.getElementById("app").innerText = "hello " + content; } module.exports = show;

style.css:

body{ background: pink; } #app{ text-align: center; }

 main.js:

const style = require("./style.css"); const show = require("./show.js"); show("webpack");

webpack.config.js:

const path = require("path"); module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: 'bundle.js' }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"] } ] }, plugins: [], devServer: {} }; 

 5、Babel

Babel实际上是一个编译JavaScript的平台,它能够编译代码帮你达到如下目的:

让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器彻底支持;

让你能使用基于JavaScript进行了拓展的语言,好比React的JSX;

Babel的安装与配置

Babel实际上是几个模块化的包,其核心功能位于称为babel-core的npm包中,webpack能够把其不一样的包整合在一块儿使用,对于每个你须要的功能或拓展,你都须要安装单独的包(用得最多的是解析Es6的babel-env-preset包和解析JSX的babel-preset-react包)。

项目目录结构以下:

package.json:

{
  "name": "test26", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --config webpack.config.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.25.0", "babel-loader": "^7.1.1", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.5.2", "babel-preset-es2015": "^6.24.1", "webpack": "^3.0.0" } } 

在webpack中配置Babel的方法以下:

const path = require("path"); module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: 'bundle.js' }, module: { rules: [ { test: /\.js$/, loader: "babel-loader" } ] }, plugins: [ ], devServer: {} }; 

如今你的webpack的配置已经容许你使用ES6以及JSX的语法了。

show.js:

function show(content){ document.getElementById("app").innerText = "hello, " + content; } module.exports = show;

main.js:

let name = "webpack!" const show = require("./show.js"); show(name);

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="./dist/main_2d6cab1e.css"/> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

其中的style.css文件无关紧要。

Babel其实能够彻底在 webpack.config.js 中进行配置,可是考虑到babel具备很是多的配置选项,在单一的webpack.config.js文件中进行配置每每使得这个文件显得太复杂,所以一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。

6、手动经过终端方式,将第三方库直接打包:

以jquery为例:

在对应的文件夹下安装jquery:

npm install jquery --save-dev

在main.js中导入jquery:

var $ = require('jquery');

导入后就能够开始使用了:

// main.js var $ = require('jquery'); document.write('<div>Hello World</div>'); $("div").html("导入jquery实例!");

文件夹结构及文件内容以下方式一:

package.json:

{
  "name": "test15", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack src/main.js dist/bundle.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "jquery": "^3.3.1", "webpack": "^3.6.0" } } 

main.js:

var $ = require('jquery'); document.write('<div>Hello World</div>'); $("div").html("导入jquery实例!");

 index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./dist/bundle.js"></script> </head> <body> </body> </html>

方式二:

package.json:

{
  "name": "test15", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "jquery": "^3.3.1", "webpack": "^3.6.0" } } 

webpack.config.js:

var webpack = require('webpack'); var path = require('path'); // 引入node的path模块 module.exports={ entry: { entry: './src/main.js' // 入口文件 }, output: { path: path.resolve(__dirname, 'dist'), // 打包路劲(获取绝对路径) filename: 'bundle.js' // 打包文件 }, module: {}, plugins: [], devServer: {}, }

 main.js:

var $ = require('jquery'); document.write('<div>Hello World</div>'); $("div").html("导入jquery实例!");

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./dist/bundle.js"></script> </head> <body> </body> </html>

 7、一切皆模块

Webpack有一个不可不说的优势,它把全部的文件都都当作模块处理,JavaScript代码,CSS和fonts以及图片等等经过合适的loader均可以被处理。

CSS

webpack提供两个工具处理样式表,css-loader 和 style-loader,两者处理的任务不一样,css-loader使你可以使用相似@import 和 url(...)的方法实现 require()的功能,style-loader将全部的计算后的样式加入页面中,两者组合在一块儿使你可以把样式表嵌入webpack打包后的JS文件中。

//安装 npm install --save-dev style-loader css-loader

8、插件(Plugins)

插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程当中生效,执行相关的任务。
Loaders和Plugins经常被弄混,可是他们实际上是彻底不一样的东西,能够这么来讲,loaders是在打包构建过程当中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操做单个文件,它直接对整个构建过程其做用。

Webpack有不少内置插件,同时也有不少第三方插件,可让咱们完成更加丰富的功能。

使用插件的方法

要使用某个插件,咱们须要经过npm安装它,而后要作的就是在webpack配置中的plugins关键字部分添加该插件的一个实例(plugins是一个数组)

下面来看一个实例:经过Plugin将注入bundle.js文件里的css提取到单独的文件中

项目目录以下:

app.css:

body { background: pink; } #app{ text-align: center; }

show.js:

function show(content){ document.getElementById("app").innerText = "hello " + content; } module.exports = show;

app.js:

require("./app.css"); const show = require("./show.js"); show("Webpack!");

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

package.json:

{
  "name": "test22", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack --config webpack.config.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "extract-text-webpack-plugin": "^3.0.2", "style-loader": "^0.23.1", "webpack": "^3.6.0" } } 

webpack.config.js:

const path = require('path'); // 引入node的path模块 const ExtractTextPlugin = require ('extract-text-webpack-plugin'); module.exports={ // JavaScript 执行入口文件 entry: { entry: './src/app.js' // 入口文件 }, output: { // 将输出文件都放到 dist 目录下 path: path.resolve(__dirname, './dist'), // 将全部依赖的模块合并输出到一个bundle.js文件中 filename: 'bundle.js' }, module: { rules: [ { // 用正则去匹配要用该 loader 转换的 css 文件 test: /\.css$/, loaders: ExtractTextPlugin.extract({ // 转换.css文件须要使用的Loader use: ['css-loader'], }), } ] }, plugins: [ new ExtractTextPlugin({ // 从.js文件中提取出来的.css文件的名称 filename:'[name]_[contenthash:8].css', }), ], devServer: {}, }

要让以上代码运行起来,须要先安装新引入的插件:

npm i -D extract-text-webpack-plugin

安装成功后从新执行构建, 咱们会发现 dist 目录下多出一个entry_23c6115b.css 文件, bundle .j s 文件里也没有 css 代码了,再将该 css 文件引入 index.html 里就完成了。

从以上代码能够看出, Webpack是经过 plugins属性来配置须要使用的插件列表的。plugins 属性是一个数组,里面的每一项都是插件的一个实例,在实例化一个组件时能够经过构造函数传入这个组件支持的配置属性。

例如,ExtractTextPlugin插件的做用是提取出JavaScript代码里的css到一个单独的文件中。对此咱们能够经过插件的filename属性,告诉插件输出的css文件名称是经过[name][contenthash:8] .css字符串模板生成的,里面的[ name]表明文件的名称,[contenthash:8]表明根据文件内容算出的8位Hash值,还有不少配置选项能够在
ExtractTextPlugin ( https://github.com/webpack-contrib/extract-text-webpack-plugin )的主页上查到。

9、使用DevServer:

实际开发中咱们可能会须要:

• 提供 HTTP 服务而不是使用本地文件预览;
• 监昕文件的变化并自动刷新网页,作到实时预览:
• 支持 Source Map ,以方便调试。

对于这些, Webpack 都为咱们考虑好了。 Webpack 原生支持上述第 2 、 3 点内容,再结合官方提供的开发工具 DevServer ( https://webpack乒org/configuration/dev-server/)也能够很方便地作到第 1 点。 DevServer 会启动一个 HTTP 服务器用于服务网页请求,同时会帮助启动Webpack,并接收 Webpack 发出的文件更变信号,经过 WebSocket 协议自动刷新网页作到实时预览。

下面在一个小项目中集成DevServer。

项目目录以下:

app.css:

body { background: pink; } #app{ text-align: center; }

app.js:

require("./app.css"); const show = require("./show.js"); show("Webpack!");

 show.js:

function show(content){ document.getElementById("app").innerText = "hello " + content; } module.exports = show;

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script src="./dist/bundle.js"></script> </body> </html>

 package.json:

{
  "name": "test23", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack --config webpack.config.js", "server": "webpack-dev-server --open" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^2.1.0", "extract-text-webpack-plugin": "^3.0.2", "style-loader": "^0.23.1", "webpack": "^3.6.0", "webpack-dev-server": "^2.9.1" } } 

首先须要安装 DevServer:

cnpm i -D webpack-dev-server

webpack.config.js:

const path = require('path'); // 引入node的path模块 const ExtractTextPlugin = require ('extract-text-webpack-plugin'); module.exports={ // JavaScript 执行入口文件 entry: { entry: './src/app.js' // 入口文件 }, output: { // 将输出文件都放到 dist 目录下 path: path.resolve(__dirname, './dist'), // 将全部依赖的模块合并输出到一个bundle.js文件中 filename: 'bundle.js' }, module: { rules: [ { // 用正则去匹配要用该 loader 转换的 css 文件 test: /\.css$/, loaders: ExtractTextPlugin.extract({ // 转换.css文件须要使用的Loader use: ['css-loader'], }), } ] }, plugins: [ new ExtractTextPlugin({ // 从.js文件中提取出来的.css文件的名称 filename:'[name]_[contenthash:8].css', }), ], devServer: {}, }

 安装成功后执行 "webpack-dev- server"或"npm run server" 命令, DevServer 就启动了,这时咱们会看到控制台有一 串日志输出:

Project is running at http://localhost:8080/ webpack output is served from /

这意味着 DevServer 启动的 HTTP 服务器监听在 8080 端口, DevServer 启动后会一直驻留在后台保持运行 ,访问这个网址,就能获取项目根目录下的 index.html 了。用浏览器打开这个地址时咱们会发现页面空白,错误的缘由是./ dist/bundle.j s 加载 404了 。 同时咱们会发现并无文件输出到 dist 目录,缘由是 DevServer 会将 Webpack 构建出的文件保存在 内存中,在要访问输出的文件时,必须经过 HTTP 服务访问。因为 DevServer不会理会 webpack .config.j s 里配置的 output .path 属性,因此要获取 bundle.js 的正确 URL 是 http: //loca lhost:8080/bundle.js,对应的 index.html 应该修改成:

<html>
<head>
<meta charset= ” UTF-8 ” >
</head>
<body>
<div id=” app ”></ div>
〈 !一导入 DevServer 输出的 JavaScript 文件一〉
<script src=”bundle.js"></script>
</body>
</ html>

模块热替换:

除了经过从新刷新整个网页来实现实时预览, DevServer 还有一种被称做模块热替换的刷新技术。模块热替换能作到在不从新加载整个网页的状况下,经过将己更新的模块替换老模块,再从新执行一次来实现实时预览。模块热替换相对于默认的刷新机制能提供更快的响应速度和更好的开发体验。模块热替换默认是关闭的,要开启模块热替换,咱们只 需在启动DevServer 时带上一 hot 参数,重启 DevServer 后再去更新文件就能体验到模块热替换的神奇了。 

支持 Source Map:

在浏览器中运行的 JavaScript 代码都是编译器输出的代码,这些代码的可读性不好。若是在开发过程当中遇到一个不知道缘由的 Bug,则咱们可能须要经过断点调试去找出问题。在编译器输出的代码上进行断点调试是一件辛苦和不优雅的事情,调试工具能够经过 Source Map( https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/)映射代码,让咱们在源代码上断点调试。 Webpack 支持生成 Source Map,只需在启动时带上一 devtool source-map参数。重启 DevServer 后刷新页面,再打开 Chrome 浏览器的开发者工具,就能够在 Sources栏中看到可调试的源代码了,如图1-2所示。

相关文章
相关标签/搜索