前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >正确的Webpack配置姿势,快速启动各式框架!

正确的Webpack配置姿势,快速启动各式框架!

作者头像
腾讯NEXT学位
修改于 2019-05-17 06:38:37
修改于 2019-05-17 06:38:37
1.7K0
举报
文章被收录于专栏:腾讯NEXT学位腾讯NEXT学位

本文介绍一些Webpack常用或者有意思的一些配置,教你快速启动各种框架(这里主要是React和Angular)。该篇我们不聊原理,只讲实战。

在去年的这个时候,本骚年还在被Grunt和Gulp以及各种Requirejs、Seajs团团围住攻击,狼狈不堪。后面认识了Webpack之后,基本所有项目框架都拿它来构建了。

当然也不包括本骚年负责项目都是纯前端的PC端单页应用的原因,还没遇到什么项目使用Webpack上太难的问题。

Hello Webpack


Webpack是一个现代的JavaScript应用程序的模块打包器(module bundler)。其实Webpack不应该拿来跟Grunt/Gulp比较的,但在本骚年这边它就是承担起了很大一部分工作。

初始Webpack

这里主要基于Webpack2来讲吧,Webpack1迁移到2还是不是特别难的,官方也配了迁移文档。 其实官方的文档也有很详细的说明了,对于一般的项目还是可以完全驾驭的。

下面我们先跟随着原始的脚步过一遍概念吧。

四个核心概念:入口(entry)、输出(output)、loader、插件(plugins)。

入口(entry)

将您应用程序的入口起点认为是根上下文(contextual root)或app第一个启动文件。 一般来说,在Angular中我们将是启动.bootstrap()的文件,在Vue中则是new Vue()的位置,在React中则是ReactDOM.render()或者是React.render()的启动文件。

123

module.exports = {entry: './path/to/my/entry/file.js'};

同时,entry还可以是个数组,这个时候「文件路径(file path)数组」将创建“多个主入口(multi-main entry)”。

常见的使用方式是我们需要把”babel-polyfill.js”这样的文件也注入进去(如果需要React的话还可以加个”react-hot-loader/patch”进去):

123

module.exports = {entry: ['babel-polyfill', './path/to/my/entry/file.js']};

出口(output)

output属性描述了如何处理归拢在一起的代码(bundled code),在哪里打包应用程序。一般需要以下两点:

  • filename: 编译文件的文件名(main.js/bundle.js/index.js等)
  • path:对应一个绝对路径,此路径是你希望一次性打包的目录

123456

module.exports = {output: {filename: 'bundle.js',path: '/home/proj/public/assets'}};

loader

webpack把每个文件(.css, .html, .scss, .jpg, etc.) 都作为模块处理。但webpack只理解JavaScript。

如果你看过生成的bundle.js代码就会发现,Webpack将所有的模块打包一起,每个模块添加标记id,通过这样一个id去获取所需模块的代码。 而我们的loader的作用,就是把不同的模块和文件转换为这样一个模块,打包进去。

loader支持链式传递。能够对资源使用流水线(pipeline)。loader链式地按照先后顺序进行编译,从后往前,最终需要返回javascript。

不同的应用场景需要不同的loader,这里我简单介绍几个(loader使用前都需要安装,请自行查找依赖安装):

1. babel-loader

官网在此,想要了解的也可以参考Babel 入门教程。 babel-loader将ES6/ES7语法编译生成ES5,当然有些特性还是需要babel-polyfill支持的(Babel默认只转换新的JavaScript句法,而不转换新的API,如Promise等全局对象)。

12345678

// 在webpack1里使用loader属性,在webpack2中为rules属性module.exports = {module: {rules: [{test: /\.(js)$/, use: 'babel-loader'}]}};

而对于babel-loader的配置,可以通过options进行,但一般更常使用.babelrc文件进行:

1234

{"presets": [],"plugins": [] // 插件}

  • presets: 设定转码规则

有”es2015”, “stage-0/1/2/3”,如果你使用React则还加上”react”,而我一般使用”lastest”装满最新特性。 当然这些都需要安装,你选择了对应的转码规则也要安装相应的依赖:

1

npm install --save-dev babel-preset-latest

2. ts-loader

一看就知道,是个typescript的loader,同样的还有awesome-typescript-loader,关于两者的不同可参考作者的话。 这里我们使用ts-loader也就足够了:

12345

{test: /\.(ts)$/,use: ["babel-loader", "ts-loader"],exclude: /node_modules/}

  1. 其他loader
  • css相关loader
    • css-loader: 处理css文件中的url()
    • style-loader: 将css插入到页面的style标签
    • less-loader: less转换为css
    • postcss-loader(autoprefixer-loader): 自动添加兼容前缀(-webkit--moz-等)
  • url-loader/file-loader: 修改文件名,放在输出目录下,并返其对应的url
    • url-loader在当文件大小小于限制值时,它可以返回一个Data Url
  • html-loader/raw-loader: 把Html文件输出成字符串
    • html-loader默认处理html中的<img src="image.png">为require(“./image.png”),需要在配置中指定image文件的加载器

插件(plugins)

loader仅在每个文件的基础上执行转换,插件目的在于解决loader无法实现的其他事。 由于plugin可以携带参数/选项,需要在wepback配置中,向plugins属性传入new实例。

这里也介绍几个常用的插件:

1. HtmlwebpackPlugin

功能有下:

  • 为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
  • 可以生成创建html入口文件,比如单页面可以生成一个html文件入口

但其实最常使用的,无非是把index.htnm页面插入(因为入口文件为js文件):

1234

new HtmlwebpackPlugin({template: path.resolve(__dirname, 'src/index.html'),inject: 'body'})

2. CommonsChunkPlugin

提取代码中的公共模块,然后将公共模块打包到一个独立的文件中,以便在其他的入口和模块中使用。

像之前有个项目有远程服务器调试代码的需求[捂脸],这时候我们需要把依赖单独抽离出来(不然文件太大了):

1234567

new CommonsChunkPlugin({name: 'vendors',filename: 'vendors.js',minChunks: function(module) {return isExternal(module);}})

关于isExternal()函数,用了很简单的方式进行:

1234567

function isExternal(module) {var userRequest = module.userRequest;if (typeof userRequest !== 'string') {return false;}return userRequest.indexOf('node_modules') >= 0; // 是否位于node_modules里}

3. webpack.ProvidePlugin

定义标识符,当遇到指定标识符的时候,自动加载模块。像我们常用的jQuery

1234

new webpack.ProvidePlugin({jQuery: 'jquery',$: 'jquery'})

4. ExtractTextPlugin 可以将样式从js中抽出,生成单独的.css样式文件(同样因为方便调试[捂脸+1])。即把所以的css打包合并:

123

new ExtractTextPlugin('style.css', {allChunks: true // 提取所有的chunk(默认只提取initial chunk,而上面CommonsChunkPlugin已经把部分抽离了)})

解析(resolve)

这些选项能设置模块如何被解析。这里本骚年只讲两个常用的:

1. resolve.extensions

自动解析确定的扩展。默认值为:

1234567

resolve: {extensions: [".js", ".json"]// 当我们需要使用typescript的时候,需要修改:extensions: [".js", ".ts"]// 当我们需要使用React时,还要修改:extensions: ['.ts', '.tsx', '.js']}

2. resolve.alias

创建importrequire的别名,来确保模块引入变得更简单。

12345

resolve: {alias: {shared: path.resolve(__dirname, 'src/shared'),}}

如果使用typescript的话,我们还需要配置tsconfig.json

1234567

{"compilerOptions": {"paths": {"shared": ["src/shared"]}}}

这样我们就可以跟长长的路径定位说拜拜了:

1234

// 原代码import {something} from '../../../../../shared/something';// 配置后import {something} from 'shared/something';

开发工具(devtool)

此选项控制是否生成,以及如何生成source map。 要开启source map,我们还需要安装source-map-loader

1

npm i -D source-map-loader

同时添加loader的配置:

123456789101112

module.exports = {module: {rules: [{test: /\.js$/,use: ["source-map-loader"],enforce: "pre"}]},devtool: 'source-map' // 然后我们就可以开启了};

webpack-dev-server

webpack-dev-server是webpack官方提供的一个小型Express服务器,主要提供两个功能:

  1. 为静态文件提供服务
  2. 自动刷新和热替换(HMR)

在实际开发中,webpack-dev-server可以实现以下需求:

  • 每次修改代码后,webpack可以自动重新打包
  • 浏览器可以响应代码变化并自动刷新

一般来说,我们可以通过引入webpack.config.js文件然后调整配置就可以启用了:

123456789

// webpackServer.config.js文件// 生成配置var webpack = require('webpack');var path = require('path'); // 引入node的path库var config = require("./webpack.config.js"); // 引入webpack.config.jsconfig.entry.concat(['webpack/hot/dev-server','webpack-dev-server/client?http://localhost:3333']);module.exports = config;

然后命令行启动:

1

webpack-dev-server --config webpackServer.config.js --host 0.0.0.0 --port 3333 --devtool eval --progress --colors --hot --content-base dist

webpack-dev-server --config webpackServer.config.js后面的都是配置,也可以在webpackServer.config.js文件中写入。

常用配置:

  • devServer.contentBase: 告诉服务器从哪里提供内容
  • devServer.port(CLI): 指定要监听请求的端口号
  • devServer.host(CLI): 指定使用一个host。默认是localhost
  • devServer.hot: 启用webpack的模块热替换特性
  • devServer.progress(CLI): 将运行进度输出到控制台。

其余配置请移步官方文档。

前端框架与Webpack


这里本骚年就不一个个讲解了,简单分享几个用过的webpack.config.js配置吧。

Angular1 + Webpack

123456789101112131415161718192021222324252627282930313233343536

var webpack = require('webpack');var CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');var ExtractTextPlugin = require('extract-text-webpack-plugin');var path = require('path');var config = {entry: {app: ['./app/bootstrap.js'] // 入口文件},output: {path: path.resolve(__dirname, 'app/entry'), // 编译后文件publicPath: '/entry/',filename: 'bundle.js' // 生成文件名},module: {loaders: [{test: /\.js$/,loader: 'babel-loader',exclude: /node_modules/}]},plugins: [// 使用CommonChunksLoader来提取公共模块new CommonsChunkPlugin({name: 'vendors',filename: 'vendors.js',minChunks: function (module) {var userRequest = module.userRequest;if (typeof userRequest !== 'string') {return false;}return userRequest.indexOf('node_modules') >= 0}})]};module.exports = config;

React + Webpack

1234567891011121314151617181920212223242526272829303132333435363738

var webpack = require('webpack');var path = require('path'); //引入node的path库var HtmlwebpackPlugin = require('html-webpack-plugin');var config = {entry: ['webpack/hot/dev-server','webpack-dev-server/client?http://localhost:3000',path.resolve(__dirname, 'app/index.js')], //入口文件output: {path: path.resolve(__dirname, 'dist'), // 指定编译后的代码位置为 dist/bundle.jsfilename: 'bundle.js'},module: {loaders: [// 为webpack指定loaders{test: /\.less$/,loaders: ['style', 'css', 'less'],include: path.resolve(__dirname, 'app')},{test: /\.jsx?$/,loader: 'babel-loader',exclude: 'node_modules'}]},plugins: [// 入口模板文件解析new HtmlwebpackPlugin({title: 'React Redux Test',template: path.resolve(__dirname, 'templates/index.ejs'),inject: 'body'})],devtool: 'source-map'}module.exports = config;

Angular2 + Typescript + Webpack

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

var webpack = require('webpack');var path = require('path');var HtmlwebpackPlugin = require('html-webpack-plugin');var config = {entry: ['babel-polyfill', './src/bootstrap.ts'],output: {path: path.resolve(__dirname, 'dist'),filename: './bundle.js'},resolve: {extensions: ['.ts', '.js']},module: {rules: [{test: /\.ts$/,use: ["babel-loader", "ts-loader", "angular2-template-loader"],exclude: /node_modules/},{test: /\.(html|css)$/,use: ['raw-loader'],exclude: [path.resolve(__dirname, 'src/index.html')]},{test: /\.async\.(html|css)$/,loaders: ['file?name=[name].[ext]']}, {test: /\.js$/,use: ["source-map-loader"],enforce: "pre"}]},plugins: [new HtmlwebpackPlugin({template: path.resolve(__dirname, 'src/index.html'),inject: 'body'}),new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)@angular/,path.resolve(__dirname, 'src'),{})],devtool: 'source-map'};module.exports = config;

结束语


很可惜,当时玩Vue本骚年是用的vue-cli,所以这里没有Vue相关的代码。不过经过上面的讲解以及课后的练习,相信你一定可以搭建自己想要的应用。 Webpack的资源很多,而深入理解的你也能去开发自己想要的loader或是插件的,多了解多尝试总是很棒的。

文章来源:腾讯工程师 王贝珊

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-02-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯NEXT学院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
webpack 入门教程
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
老马
2018/08/20
4.1K0
webpack 入门教程
webpack 基础知识整理
webpack是一个 模块打包工具,支持所有的打包语法,比如 ES Module、CommonJS、CMD、AMD。初期的webpack是用来模块打包js的,发展到现在,已经可以打包很多种文件类型,比如 css、img 。
神葳
2021/01/22
1.4K0
前端工程化 - webpack 基础
默认配置文件 webpack.config.js,可以通过 webpack --config 指定配置文件
Cellinlab
2023/05/17
3100
从零认识webpack4.0,带你走进神秘的webpack
前言: 作为一个现代javascript 应用程序的静态模块打包器,webpack能将各种资源,如js,css, 图片等作为模块来处理,是当下前端工程化的一个很受欢迎的工具,webpack目前最新的版本是4.0,文章将在4.0 的基础上,从使用者的角度,一步步教你认识并搭建一个简单的webpack配置项目,当然webpack的配置和使用较为丰富且复杂。
前端老鸟
2019/07/29
4900
从零认识webpack4.0,带你走进神秘的webpack
webpack 4.x 初级学习记录
以上就是4版本之前的使用方式,但是这种方式在4版本中就不能使用了,4版本有自己的新的方式
SpiritLing
2018/10/10
7570
还学不会webpack?看这篇!
Webpack已经流行好久了,但很多同学使用webpack时还是一头雾水,一下看到那么多文档、各种配置、各种loader、plugin立马就晕头转向了。我也不例外,以至于很长一段时间对webpack都是一知半解的状态。但是想要继续做好前端,webpack是必须得跨过的一道坎,其实掌握webpack并不难,只是我们没有找到正确的方法。本文就是我自己在学习webpack时的一点心得体会,供大家参考。
MudOnTire
2019/07/02
5100
还学不会webpack?看这篇!
Webpack之阿拉丁神灯
现今的web,都很丰富,它们拥有着复杂的JavaScript代码,一大堆依赖包,为了简化开发的复杂度,前端世界出现了很多很好的实践方法。
江米小枣
2020/06/15
6220
四大维度解锁webpack3笔记
在命令行输入webpack -h,成功就出现下图,有很多webpack命令可以看一看
FinGet
2019/06/28
1.1K0
四大维度解锁webpack3笔记
Webpack基本使用
Webpack介绍:主要用于web项目中打包资源进行自动构建,Webpack将所有资源视为JS的模块来进行构建,所以对于CSS,Image等非JS类型的文件,Webpack会使用相应的加载(loader)器来加载成其可识别的JS模块资源,通过配置一些信息,就能将资源进行打包构建,更好地实现前端的工程化 Webpack安装 本地安装: npm install -D webpack -D 实际上是简写 --dev-save 如果你使用Webpack 4+ 版本, 你还需要安装CLI. npm ins
一个淡定的打工菜鸟
2018/09/06
4660
Webpack基本使用
谈谈webpack2的一些事
从v1迁移到v2 1. 配置类型 在webpack1的时候,主要是通过导出单个object来进行配置。例如下面的配置: // webpack1 导出方式 module.export = { entry : 'app.js', output : { */... */}, /* ... */ }; 而在webpack2中,则有三种方式来灵活配置,可以针对不同的场景。 1.1 通过不同环境变量导出不同的配置文件 // 可以有两种方式传递当前值,一种是简单传递字符串,另外一种则是传递一个对象
糊糊糊糊糊了
2018/05/09
1.3K0
十七.Webpack的使用
webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;
Yuyy
2022/06/28
6750
webpack3.x文件配置
webpack3.x 主配置webpack.config.js文件,每个模块的详细信息都有一定的注释,如果有不对的地方,还请指教!
White feathe
2021/12/08
9410
webpack入门指南
1. 导语 github仓库 https://github.com/Rynxiao/webpack-test 1.1 什么叫做webpack webpack is a module bundler. webpack takes modules with dependencies and generates static assets representing those modules. 简单的概括就是:webpack是一个模块打包工具,处理模块之间的依赖同时生成对应模块的静态资源。 1.2 web
糊糊糊糊糊了
2018/05/09
2.4K0
webpack入门指南
10天从入门到精通Vue(五)Webpack打包
webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;
共饮一杯无
2022/11/28
5280
10天从入门到精通Vue(五)Webpack打包
webpack配置React开发环境(上)
Webpack 是一个前端资源加载/打包工具,我们部门的一条主要技术栈就是Webpack+React+ES6+node,虽然之前自己做个人项目也接触好多次Webpack,但是自己并没有研读总结过Web
牧云云
2018/05/02
1.7K0
webpack5快发布了,你还没用过4吗?
webpack5 预计会在 2020 年年初发布,之前从 alpha 版本就有关注,本次重点更新在长期缓存,tree shakking 和 es6 打包这块。具体变更可以参考https://github.com/webpack/changelog-v5/blob/master/README.md。
前端森林
2020/04/23
1.6K0
webpack5快发布了,你还没用过4吗?
webpack 热更新(实施同步刷新)
实现热更新,首先,安装一系列的node命令,如果嫌麻烦,你可以直接看解决方案二,相对来说比较简单。
White feathe
2021/12/08
8840
webpack 热更新(实施同步刷新)
vue 学习笔记第四弹 - Webpack
webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;
syy
2020/04/07
9050
Webpack5构造React多页面应用
来源 | https://github.com/zhedh/react-multi-page-app/
winty
2021/01/07
3.8K0
webpack配置完全指南
首先webpack是一个静态模块打包器,所谓的静态模块,包括脚本、样式表和图片等等;webpack打包时首先遍历所有的静态资源,根据资源的引用,构建出一个依赖关系图,然后再将模块划分,打包出一个或多个bundle。再次白piao一下官网的图,生动的描述了这个过程:
gogo2027
2022/10/03
1.3K0
相关推荐
webpack 入门教程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档