Webpack快速入门实践

webpack

源起

能碰上 webpack,是偶然也是必然。本来想在公司下个项目试试 AngularJS,但是又不能使用 server。奇怪要求的限制,滋生了奇怪的请求,所以在 Google 上查了半天没有找到合理的解决方案,只在 Google Group 里面看到有两个人讨论的热火朝天,里面提到了 webpack.config.js 貌似能够成功解决能够这个问题,尝试了下,老是有问题,就开始读 webpack 文档。之后在看第一个 AngularJS 2 教程时,直接看到一句大意是,如果你还不懂什么是 webpack,那你先别来看这个了,回家再进修进修吧。 不禁好奇,这东西那么好用?更仔细的研究了下,应用确实挺广的,而且很实用。废话不多说,直接上教程。从 0 开始创建一个 webpack 项目,一边往里面加内容,一边介绍。

简介

Webpack 是什么呢?官网介绍是 module bundler, JavaScript 的模块打包器,参考题图,大概意思就是,能够将一堆关系错综复杂的 .js, .css, .sass 等文件,打包成几个静态的文件,在 html 里面直接插入实用,就好像在一家淘宝店上买了许多东西, 卖家不是一个一个给你发货而是给你打包送过了,省去了你一个一个收快递的麻烦。举一个简单的栗子,

//bar.js
export default function bar() {}

//app.js
import bar from './bar';
bar();

在使用 html 里使用时,需要分别加载两个文件 bar.jsapp.js,通过 webpack 转换成一个 bundle.js 之后,就只需要 <script src="bundle.js"></script> 这么一个文件就可以了,对于一个有几十个 js 文件的项目来说,简直是不可多得。怎么做到的?还是很懵逼?Webpack 有四个核心概念,接下来是一步一步的解释。

首先,确认电脑里面已经安装了 npmnode, 在 terminal 输入 npm -vnode -v 可以查看,没有的话随便搜索都可以找到。然后我们就可以正式开始 webpack 之旅了。

安装

新建一个文件夹,并进入文件夹

mkdir webpack-tut
cd webpack-tut

初始化

npm init 
/* 命个名,其他的都回车跳过
   name: (webpack-tut) webpack-starter
   version: (1.0.0)
   description: webpack-starter */

完成后文件夹里有多出一个package.json文件,是整个项目的配置文件。

在该项目目录下 安装 Webpack。如果是第一次安装,也在全局环境下安装。

npm i -D webpack
npm i -g webpack // 全局安装

运行完后,会出现名为 node_modules 的文件夹,里面一堆的 library,这个文件夹就放着就行,不用去管它。
注意看一下 webpack 的版本,2017年4月8日还是2.3.3,如果版本过低可能会出现一些问题,可以选择安装某个版本

npm i -D webpack@<version> //e.g. npm i -D webpack@2.3.3

创建第一个 webpack 应用

新建两个文件夹 src,dist。打包前的文件放在 src 里,文件会自动打包后放在 dist 里。

mkdir src
mkdir dist

在根目录里新建文件 webpack.config.js,并在 src 里新建文件 app.js,两个文件的代码如下:

// app.js
console.log('Hello world');

// webpack.config.js
module.exports = {
    entry: './src/app.js',
    output: {
        filename: './dist/app.bundle.js'
    }
}

在根目录下运行webpack:

webpack -d

就能看到一个 app.bundle.js 的文件自动生成在了 dist 文件夹里。在文件末尾,可以看到

/*!********************!*\
  !*** ./src/app.js ***!
  \********************/
/***/ (function(module, exports) {
eval("console.log('Hello');\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9hcHAuanM/N2FjOSJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zb2xlLmxvZygnSGVsbG8nKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2FwcC5qc1xuLy8gbW9kdWxlIGlkID0gMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwibWFwcGluZ3MiOiJBQUFBOyIsInNvdXJjZVJvb3QiOiIifQ==");
/***/ })

恭喜你已经成功的使用了一次 webpack。

先讲上面过程涉及的 Webpack 里两个核心的概念 entry(入口) 和 output(输出) ,entry 是初始文件的路径,output 是自动生成后的文件路径和文件名。

将文件自动插入 HTML 中

初步使用

首先安装 html-webpack-plugin

npm install html-webpack-plugin --save-dev

修改文件 webpack.config.js,在 output 里加入 路径,并加入 plugins

// webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/app.js',
    output: {
        filename: './dist/app.bundle.js'
    },
    plugins: [new HtmlWebpackPlugin()]
}

运行 webpack -d, 自动生成了 index.html,并且自动把打包后的文件 app.bundle.js 加到了里面。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
  <script type="text/javascript" src="app.bundle.js"></script></body>
</html>

自定义

html-wepack-plugin 允许我们能够自定义一些内容,比如说使用固定的模版。接下来讲下如何用固定的 html 模版去生成文件。首先修改 webpack.config.js

// webpack.config.js
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.bundle.js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Title From Config',
            hash: true,
            filename: 'index.html',
            template: './src/index.html'
        })
    ]
}

在 src 目录下新建文件 index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
        <p>You are awesome.</p>
    </body>
</html>

运行 webpack -d, 结果生成的 index.html 为:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Title From Config</title>
    </head>
    <body>
        <p>Some contents here, some others</p>
    <script type="text/javascript" src="app.bundle.js?0b89768d13f4a86e6d19"></script></body>
</html>

使用了 src 文件夹下的 index.html 为模版,传递了webpack.config.js 里的 title 的值,并且对生成的 app.bundle.js 未见进行了 hash 处理。

更多关于 html-webpack-plugin 的配置,可以看看官方文档:https://github.com/jantimon/html-webpack-plugin

这部分涉及到 webpack 另外一个核心概念:plugins。plugins 是 webpack 的支柱功能,扩展了 webpack 的功能。

载入 CSS

首先,还是要安装一下相应的库。

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

下一步就是进行 webpack 的配置,在 webpack.config.js 里进行,修改后如下:

// webpack.config.js
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Title From Config',
            hash: true,
            filename: 'index.html',
            template: './src/index.html'
        })
    ]
}

在 src 目录下,新建 app.css

// app.css
body {
    background-color: lightblue;
}

运行 webpack -d,双击打开 dist/index.html,背景是浅蓝色的,但是 dist 文件夹里没有多处一个 app.css 的文件,那是因为 css 文件在加载的过程中,被转换打包到了 app.bundle.js 里面了,在这之中起作用的就是 webpack 的最后一个核心概念,loaders(加载器)。loaders 的作用就是对资源文件进行转换。

总结

通过基础入门,和加载 HTML, CSS,将 Webpack 的四大核心概念讲完啦:

  • entry 是初始文件的路径
  • output 是自动生成后的文件路径和文件名。
  • loaders 的作用是对资源文件进行转换。
  • plugins 是 webpack 的支柱功能,扩展了 webpack 的功能。

全部文件代码:

// package.json
{
  "name": "webpack-starter",
  "version": "1.0.0",
  "description": "webpack-starter",
  "main": "index.js",
  "scripts": {
    "dev": "wepack -d"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^0.28.0",
    "html-webpack-plugin": "^2.28.0",
    "node-sass": "^4.5.2",
    "style-loader": "^0.16.1",
    "webpack": "^2.3.3"
  }
}


// webpack.config.js
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Title From Config',
            hash: true,
            filename: 'index.html',
            template: './src/index.html'
        })
    ]
}

// src/app.js
const css = require('./app.css');
console.log('Hello');

// src/app.css
body {
    background: lightblue;
}

// src/index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
        <p>Some contents here, some others</p>
    </body>
</html>

全文借鉴了视频 Webpack 2 Tutorial by Ihatetomatoes
看完前几个视频并跟着做,大改要40分钟到1小时。
看这篇的话可以快很多。

写这种技术类的,各种粘代码的真实耗时费力。感谢那些好好写文档的程序员们!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容