配置Webpack4支持ES6/TypeScript/异步文件引用加载
栏目: JavaScript · 发布时间: 6年前
内容简介:由于Webpack以及它的周边工具babel等更新过快,在当前的时间线来看,很多相关的文章已被版本所淘汰,已经不足以借鉴来搭建一个可以正常使用的环境,所以打算写来记录一下。在写这篇文章的时候我会同步搭建本地环境,尽量避免有略过的细节部分。熟悉初始化项目的亲可直接跳过。
由于Webpack以及它的周边工具babel等更新过快,在当前的时间线来看,很多相关的文章已被版本所淘汰,已经不足以借鉴来搭建一个可以正常使用的环境,所以打算写来记录一下。
在写这篇文章的时候我会同步搭建本地环境,尽量避免有略过的细节部分。
环境起步
熟悉初始化项目的亲可直接跳过。
首先请保证node与npm版本不要过旧,我目前的版本: node v10.15.3 / npm 6.4.1
创建并进入文件夹my-webpack 并在命令行
npm init -y 复制代码
然后打开生成的package.json 修改scripts的内容,新增build命令,一会儿我们会用到
"scripts": {
"build": "webpack"
},
复制代码
安装webpack环境,推荐使用yarn安装,语法与npm差不多,但好处在于安装快,排查错误方便。
yarn add webpack webpack-cli --dev 或 npm install webpack webpack-cli --save-dev 复制代码
安装完成后在当前目录创建webpack.config.js 写入基础配置
const path = require('path');
module.exports = {
mode : 'development',//开发环境模式
entry : {
main : './src/index.js'//入口配置
},
output : {
filename : 'bundle.js',//输出配置
path : path.resolve(__dirname, './build')
}
}
复制代码
这时候这个只具备鸡肋功能的webpack环境我们就搭建好了,接下来我们将给鸡肋插上 小翅膀 ʚɞ
配置编译ES6的Loader
此处先不介绍实际代码,因为随着版本迭代,文章中的代码语法等终究会被淘汰,我们应该学会如何去使用新版本,或者说躲过旧版本语法的坑
打开github搜索babel-loader,第一个结果就是了,打开后向下滚动查看它的介绍:
它已经清楚的介绍了此loader的支持环境 需要webpack 4作为基础环境支持
我们按照它的介绍安装loader,由于webpack刚才我们已经安装过了,此处可以去掉,但我们需要做浏览器兼容,在命令行中多加入一个 @babel/polyfill的扩展 如下↓
yarn add babel-loader @babel/core @babel/preset-env @babel/polyfill --dev 复制代码
安装完成后我们开始修改webpack.config.js
让其支持Loader的编译,此处你不需要记得清楚loader如何配置,在刚才babel-loader介绍安装方式的下方有教你如何配置,直接拿来粘贴即可:
entry..
output...
//重复代码略过 同级写入
module : {
rules : [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader'
}
}
]
}
复制代码
实际使用webpack.config.js的配置项非常之多,babel-loader的options也有很多需要配置的,此处我们已经删掉了loader中options这个键值,在当前目录下新建 .bebelrc 文件
配置它的options:
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": ["> 1%","last 2 versions","Android >= 3.2", "Firefox >= 20","iOS 7"]
},
"corejs":2,
"useBuiltIns": "usage"
}
]
]
}
复制代码
配置参数的介绍
- @babel/preset-env : 是babel编译的基础库,它下个对象中的参数,是针对于它默认配置的重定义 ↓
- targets :即在编译时根据我们的需求写入浏览器版本进行兼容
- useBuiltIns :默认值为false,它很重要,我们此处改为"usage",即为按需引入:是否只编译你脚本中使用过的API,如Promise,如果为false则不会使用polyfill进行编译
- corejs :配合useBuiltIns使用,告诉它编译时使用哪儿个core-js的版本作为核心库进行编译,如果不声明也可以正常运行,但是命令行会有警告提示说这样做是有隐患的,所以我们在此处声名大版本为 2 即可,那么如何查看我们corejs的大版本呢,它又是什么时候安装的呢?其实在安装@babel/polyfill的时候就已经被自动安装上了,我们只需要找到扩展node_moudules/@babel/polyfill 查看它package.json中记录的文件依赖,它里面会清楚写着core-js的版本号,而corejs我们也可以手动安装,但默认版本corejs已经是3起步了,所以通过@babel/polyfill默认安装即可
除了@babel/preset-env还有其他可以使用的编译库,英文好的可以直接看官方文档,或者简单了解下配置的其他参数
编译代码看效果
创建src文件夹,并新建index.js 我们试一试Promise与ES6语法能否在IE下正常运行
//index.js
const imgPromise = (imgSrc) => {
return new Promise((resolve, reject)=>{
const img = new Image();
img.onload = () =>{
resolve(img);
}
img.onerror = () => {
reject();
}
img.src = imgSrc;
});
}
const newImgSrc = 'http://b.hiphotos.baidu.com/image/h%3D300/sign=77d1cd475d43fbf2da2ca023807fca1e/9825bc315c6034a8ef5250cec5134954082376c9.jpg';
const newImg = new imgPromise(newImgSrc).then((img)=>{
document.body.appendChild(img);
},()=>{
console.log("img error");
});
复制代码
编译输出它,即在目录中生成build文件夹与bundle.js文件 ↓
npm run build
在build文件夹中创建index.html,引入bundle.js
(html文件可以通过配置webpack的HtmlWebpackPlugin来自动生成,此处手动创建,只为看到编译效果)
然后使用IE打开index.html文件即可看到图片加载,到这里,我们ES6语法 & API的编译功能就大功告成了~
支持TypeScript
同配置babel-loader的方法一样,直接去github搜索编译TypeScript的 ts-loader 安装它
yarn add ts-loader typescript --dev 复制代码
在webpack配置文件的rules数组中增加ts-loader
//webpack.config.json
rules:[
...babel-loader,
{
test: /\.tsx?$/,
exclude: /(node_modules)/,
loader: "ts-loader"
}
]
复制代码
同理,在项目根目录新增一个 tsconfig.json 配置ts-loader
//tsconfig.json
{
"compilerOptions": {
"module": "UMD",
"target": "es5",
"sourceMap": true,
"allowJs": true
},
"exclude": ["node_modules", "dist", "build", "mock"]
}
复制代码
- module :模块的引入方式
- target :编译后的运行环境
- allowJs :允许编译JS文件
- 更多配置介绍中文 /英文
开始编译TypeScript
在src目录创建一个TS文件
//test.ts
interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
export default greeter;
复制代码
然后通过import形式引入它
//index.js
import greeter from './test.ts'
...省略之前测试Promise的代码
let user = { firstName: "Jane", lastName: "User" };
console.log(greeter(user));
复制代码
执行编译后我们可直接打开build/index.html文件,打开控制台查看console
即可看到TS文件被成功编译,IE11也可正常使用,还可以在控制台看到它编译后的代码:
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (factory) {
if ( true && typeof module.exports === "object") {
var v = factory(__webpack_require__("./src sync recursive"), exports);
if (v !== undefined) module.exports = v;
}
else if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__, exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function greeter(person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
exports.default = greeter;
});
复制代码
脚本异步引用加载
本文的最后一个环节,也是开发中会经常用到的功能
如果一次加载大量的文件,或有些代码并不需要在页面初次进来的时候进行加载,可以很好地优化项目的加载速度。
在output中新增chunkFilename 意为分割后文件的命名规则
//webpack.config.js
output:{
...,
chunkFilename: '[name].bundle.js'
}
复制代码
安装@babel/plugin-syntax-dynamic-import并扩展babel-loader配置,使其支持动态文件引入
yarn add @babel/plugin-syntax-dynamic-import --dev
//扩展.babelrc 新增plugins参数
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": ["> 1%","last 2 versions","Android >= 3.2", "Firefox >= 20","iOS 7"]
},
"corejs":2,
"useBuiltIns": "usage"
}
]
],
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
复制代码
通过import动态引入文件 webpackChunkName注释的值test 会在 chunkFilename的[name]中使用
//index.js增加以下代码
function getTest(obj){
return import(/* webpackChunkName: "test" */ './test.ts').then(({default:test})=>{
console.log(test(obj));
}).catch(error=>{
console.log(error);
})
}
//或者使用async/await来处理异步插件
async function getTest(obj){
await import(/* webpackChunkName: "test" */ './test.ts').then(({default:test})=>{
console.log(test(obj));
}).catch(error=>{
console.log(error);
})
}
document.body.onclick = () =>{
let user = { firstName: "Jane", lastName: "User" };
getTest(user);
}
复制代码
此时命令行运行
npm run build
输出文件
bundle.js 91.5 KiB test.bundle.js 1.95 KiB 复制代码
此时我们可以打开index.html 开启F12看到页面只加载了bundle.js
当你点击了图片时会动态加在test.bundle.js,并在命令行中输出
Hello, Jane User
简单的代码分割与动态加载就实现了,但实际业务中存在很多公用的脚本,不能将所有的代码都进行分割
而我这里只写了异步加载的代码分割,还有同步代码的分割可进行设置,有很多参数需要配置,需要耐心的了解
尾儿
webpack的配置经常随着时间变化而改变,希望能避免配置新版本环境时不必要的踩坑 ~
而要写全所有功能的配置需要大量的时间,暂且没有精力,所以目前先写这种虽然精简却能用到的功能。
只要学会如何自己去找到配置babel-loader的方法,配置其他CSS-loader等也都可以一并学会了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 介绍同步加载、异步加载、延迟加载[原创]
- 基于echarts异步加载数据之多个series加载实例
- 使WPF图像加载异步
- CSS 异步加载技术 不影响页面渲染
- Vue异步组件处理路由组件加载状态
- 简单的算法-解决页面脚本异步加载顺序问题
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro JavaScript Design Patterns
Dustin Diaz、Ross Harmes / Apress / 2007-12-16 / USD 44.99
As a web developer, you’ll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power......一起来看看 《Pro JavaScript Design Patterns》 这本书的介绍吧!