现代Web开发教程系列_02

引言

本文从一个很小的前端工程说起,慢慢推导出我目前多个项目前端实践的工程结构。

为Web前端项目建工程

Web工程需要建工程吗?不是建个目录就可以开搞的吗?你一定会这么问。但事实上面对越来越复杂的前端页面逻辑,真的有必要好好组织一下前端的代码结构。同时前端代码的依赖管理、编译方式真的需要考量一下。

mkdir -p demo1
cd demo1
npm install # 回答一系列回答后,一个npm工程就建好了

创建前端源代码目录及编译后产物目录

从Java带来的习惯,我是不习惯将源代码与编译后的产物放在一起的,还是分开一点好。

mkdir web-src #前端源代码目录
mkdir public #前端源代码编译后产物目录

来一个Hello World

在web-src目录下写一个JS版的hello world

web-src/js/demo1.js

console.log('Hello World!');

写编译脚本

在demo1目录中执行命令安装webpack

npm install webpack --global #--global是安装到系统全局
npm install webpack --save-dev #--save-dev是安装到node_modules目录下,并修改package.json文件,添加此开发依赖

在demo1目录建一个webpack.config.js文件,在这里配置如何使用webpack编译。

webpack.config.js

var webpack = require("webpack");

var output_options = {
    path: 'public',
    publicPath: '/demo1/',
    filename: 'js/[name].js',
    hotUpdateMainFilename: 'hot-update/[hash].hot-update.json',
    chunkFilename: 'js/chunks/[name].js',
    hotUpdateChunkFilename: 'hot-update/chunks/[id].[hash].hot-update.js',
};

var entries = {
    demo1 : __dirname + '/web-src/js/demo1.js'
};

var webpackConfig = {
    entry: entries,
    output: output_options
};

module.exports = webpackConfig;

这时在demo1目录下执行webpack命令,就会在public/js目录下生成编译后的js文件

webpack

你打开public/js/demo1.js一看,肯定吓一跳,就一个简单的hello world,怎么就编出这么大的文件,这个是脱裤子放屁。如果这个系列你继续看下去,你会发现这一些也是值得的。

生成html页面

光编出js文件,如果没法在浏览器里查看运行效果也是白搭,我不建议自己手工写html页面来引用生成的js文件,还是让webpack来做吧。

安装webpack生成html的插件

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

在web-src/html目录下创建html的模板文件

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title><%= htmlWebpackPlugin.options.title || 'Webpack App'%></title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit">
    <% for (var css in htmlWebpackPlugin.files.css) { %>
    <link href="<%= htmlWebpackPlugin.files.css[css] %>" rel="stylesheet">
    <% } %>
</head>
<body class="body-cls">
    <% for (var chunk in htmlWebpackPlugin.files.chunks) { %> <script src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script> <% } %>
</body>
</html>

在webpack.config.js文件加入几行

...

var HtmlWebpackPlugin = require('html-webpack-plugin');

var createHtmlDef = function(opts){
    return new HtmlWebpackPlugin({
        title: 'demo1',
        filename: opts.path,
        template: 'web-src/html/base.html',
        chunks: opts.chunks,
        hash: true,
        inject: false
    });
};

var plugins_options = [
    createHtmlDef({path: 'demo1.html', chunks: ['demo1']})
];

var webpackConfig = {
    ...
    plugins: plugins_options,
    ...
};

...

然后在demo1目录下执行webpack命令,即完成编译

webpack

部署到nginx里

我本机安装了nginx,因此就直接把这个小demo部署到nginx里吧

ln -sf demo1/public /usr/local/var/www/demo1

最后在浏览器里访问http://127.0.0.1/demo1/demo1.html,打开chrome的控制台,应该就可以看到Hello World了。这么费劲才搞了个hello world, 确实很无聊,下篇我们在页面上做点好玩的。本篇源代码地址

webpack的一些概念

本篇里出现了不少webpack的概念,这里简单介绍一下,详细的可以参考官方文档

webpack里有三个概念:入口文件(entry),分块(chunk),模块(module)。

module指各种资源文件,如js、css、图片、svg、scss、less等等,一切资源皆被当做模块。

chunk:包含一个或者多个资源,必须可以被其它资源用require依赖。

entry:入口,也是包含了一个或者多个资源,它是一种特殊的chunk,不是一定得能被其它资源依赖,通常是使用html标签直接引入到页面里的。

比如本篇中项目执行webpack命令的输出如下

Hash: 7bd5b3403fe5f918821c
Version: webpack 1.13.0
Time: 528ms
      Asset       Size  Chunks             Chunk Names
js/demo1.js    1.42 kB       0  [emitted]  demo1
 demo1.html  318 bytes          [emitted]
   [0] ./web-src/js/demo1.js 29 bytes {0} [built]
Child html-webpack-plugin for "demo1.html":
        + 3 hidden modules

这里可以看到entry里配置的名称为demo1的entry生成了一个同名的chunk, 该chunk的编号为0,该chunk最后编译生成了js/demo1.js。而通过HtmlWebpackPlugin插件生成了demo1.html,该插件的配置里写明了生成的html页面需要引入名称为demo1的chunk,因此最后生成的html页面里就用script标签引入了js/demo1.js,并且由于hash: true,引入的url后面还加了hash,以避免浏览器缓存js。

事实上除了定义entry的方式间接声明一个chunk外,还有另一种方法,这个后面会遇到,到时再说吧。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

SSO单点登录使用token机制来验证用户的安全性

登录的业务逻辑 { http:是短连接. 服务器如何判断当前用户是否登录? // 1. 如果是即时通信类:长连接. /...

6885
来自专栏linux驱动个人学习

Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)

因此当前linux的调度程序由两个调度器组成:主调度器,周期性调度器(两者又统称为通用调度器(generic scheduler)或核心调度器(core sch...

3482
来自专栏北京马哥教育

Linux 系统结构详解

Linux系统一般有4个主要部分: 内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管...

6123
来自专栏网络

Nginx 系列实用教程#2:性能

协作翻译 原文:Nginx Tutorial #2: Performance 链接:https://www.netguru.co/codestories/ngi...

2356
来自专栏landv

robocopy的用法,数据库局域网备份

2392
来自专栏左瞅瞅,右瞅瞅

nc命令详解

NetCat,在网络工具中有“瑞士军刀”美誉,其有Windows和Linux的版本。因为它短小精悍(1.84版本也不过25k,旧版本或缩减版甚至更小)、功能实用...

3141
来自专栏FreeBuf

挖洞经验 | 一个价值$3133.7美金的Google漏洞

在对Google的安全研究中,由于其云服务平台“cloud.google.com” 具备多种功能,感觉有点意思,所以某天我决定来深入测试一下它。

1535
来自专栏coding for love

进程与线程,单核与多核1. 简介2. 程序3. 进程4. 线程5. 多进程与多线程的选择6. 小结参考

用户打开浏览器,其实就是打开了浏览器应用程序。那么什么是程序呢?我们常说浏览器是多线程的,JS 是单线程的,那么什么是线程呢?说到线程,和我们常说的进程有什么关...

3923
来自专栏帘卷西风的专栏

linux的一些运维指令和技巧

转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)

840
来自专栏分布式系统进阶

Kafka的消息是如何被消费的?Kafka源码分析-汇总

1853

扫码关注云+社区

领取腾讯云代金券