设置带有Webpack 3的开发环境

设置带有Webpack 3的开发环境学习如何使用Webpack3和Babel为JavaScript应用程序创建自己的dev、prod和遗留浏览器环境。获得高级管理人员手册的重要趋势

欢迎大家来到IT世界,在知识的湖畔探索吧!

学习如何使用Webpack 3和Babel为JavaScript应用程序创建自己的dev、prod和遗留浏览器环境。

获得高级管理人员手册的重要趋势、技巧和战略,以竞争和赢得数字经济。

我注意到一些人仍然在编写JavaScript的古老的ES5语法,这令人沮丧。我想知道是什么阻止他们继续前进。一些人必须受到心理惰性的驱使,但有些人可能只是觉得它太复杂了,无法让他们的新语法在广泛的浏览器中运行。

事实上,现在,我们不必再害怕它了。我们可以设置一个开发环境,在这个环境中,工具决定了代码需要什么转换,以及根据选定的目标(支持的用户代理列表)来加载什么多填充。这些人唯一需要开始“新生活”的是一个合适的设置。

这就是这篇文章的主题。

我的故事

在2012年,我正在寻找一种方法,将我众多的JavaScript模块合并成一个包。我在YUI loader方面有丰富的经验,但是我不想在HTTP 1的时候使用异步加载。它造成了无法忍受的滞后。

我注意到一些项目只是在页眉和页脚之间连接文件。在我的PHP背景下,我看到它更像一个include,或者更确切地说是一个import语句,所以可以控制捆绑。我创建了一个小工具https://github.com/dsheiko/jsic。不久,我发现其中包括了不那么方便,因为他们不关心范围。

然后,我想如果我有一个预编译阶段,为什么不把CommonJS符号(像Node.js)解析成一个bundle文件呢?今年年底,我想出了另一个工具:https://github.com/dsheiko/cjsc。

当发布NPM,寻找合适的措辞描述,我跑进Browserfy…是的,这是我,这不是可以解决的。尽管如此,我多年来一直依赖CJSC,这对我很有帮助。它是快速的,非常简单的设置,并且只专注于一个任务-捆绑CommonJS模块。

然而不久之后,新的解决方案开始出现。我记得,在RollUp中,树摇晃的想法给我留下了深刻的印象。我通常对YAGNI很挑剔,所以感觉就像一个梦。至于Webpack,老实说,我一开始并没有得到它。但是我参与了,而且我认为它现在是一个前端开发人员可用的最好的技术之一。

如果你知道如何处理它,当然…

满足Webpack

Webpack是什么?它是一名bundler——而且是非常聪明的一个。它读取指定的源,如果需要的话,它将被传输。接下来,TypeScript、CoffeeScript等)、解析JavaScript模块(ES模块、CommonJs、AMD)和其他依赖关系(HTML、CSS、SASS、图像等等),并生成一个或多个输出文件。

是的,您可以优雅地将代码库拆分为bundle以获得更好的用户体验。您可以有一个基本的包,代码实现核心用户体验和其他捆绑延迟加载按照他们的优先级。Webpack做的是树的晃动和范围的提升。更重要的是,您可以使用像Uglify这样的插件来处理输出代码。令人印象深刻的,不是吗?让我们举个例子,在实践中看看。

熟能生巧

首先,我们用例子克隆我的样板:

git clone https://github.com/dsheiko/boilerplate/

cd boilerplate/webpack-babel

这个应用程序做的不多。它仅仅显示了几个模块如何静态地解决问题,而另一些模块则通过使用ES动态解析。下一个语法。查看条目脚本:

/webpack-babel/src/index.js

import { utilFoo } from “./util/foo”;

这里我们静态导入foo模块。此代码将包含在主包中。

import { utilBar } from “util/bar”;

我们也使用bar模块,但是这次,我们指定它的位置——不是相对于入口脚本,而是指向基目录,我们将在Webpack配置中设置这个目录。

Promise.all([

import( “./widget/foo” ),

import( “./widget/bar” )

]).then( ([{ widgetFoo }, { widgetBar }]) => {

console.log( “Lazy-loaded modules exports “, widgetFoo(), widgetBar() );

}).catch(( e )=> {

console.error( e );

});

我们还解决了两个动态模块。根据承诺。所有的,当主bundle执行时,它们会同时开始加载。当两个负载时,我们接收它们的导出并将它们转发到控制台。如您所见,我们使用Webpack注释,例如/* webpackChunkName:“foo”*/来指出我们想要的bundle文件的名称。

该示例包含一个现成的清单(package.json)。因此,您可以通过运行获得所有所需的依赖项:

npm i

我们从Webpack想要的是:

  • Transpile ES。我们在JavaScript中使用的下一个语法适用于更广泛的浏览器。

  • 从入口脚本中解析所有遇到的(静态和动态)模块。

  • 用于生产的小包装。

  • 生成两个包:一种是常绿浏览器的薄层,另一种是为传统浏览器提供的

配置Webpack

为了避免代码重复和获得更好的可读性,我们将Webpack配置分成了四个文件:webpack.common.js、webpack.dev.js、webpack.prod。js和webpack.common-legacy.js。第一个是一个抽象的配置,由其他的配置扩展。js将为开发和Webpack.dev.js提供扩展,以进行代码优化。最终,它将被webpack.common legacy.js扩展到传统浏览器所需要的多填充。

让我们从基础开始。

webpack.common.js

module.exports = {

entry: {

index : join( SRC_FULL_PATH, “index.js” )

},

output: {

path: PUBLIC_FULL_PATH,

filename: `[name].js`,

chunkFilename: `[name].v${pkg.version}.widget.js`,

publicPath: PUBLIC_PATH

},

在这里,我们指定入口脚本位置并给它一个别名(索引)。接下来,我们设置输出配置。对于主包名,我们使用一个占位符(name),它接收我们已经设置的别名(索引)。对于延迟加载的模块,我们定义一个名称模板和基本公共路径。注意,我将清单版本添加到区块名称中。因此,我们使用项目的每一个新发布版本来破坏CDN缓存。

resolve: {

modules: [

“node_modules”,

SRC_FULL_PATH

],

extensions: [ “.js” ]javascript:void(0)

},

通过字段解析,我们声明,在解析模块时,Webpack必须尝试搜索相对于相应的NPM包和我们的基本目录(在常量SRC_FULL_PATH中给出)的文件。

plugins: [

new CleanWebpackPlugin([ PUBLIC_PATH ])

]

};

最后,我们调用clean- Webpack -plugin来清理每次Webpack即将在那里编写构建资产时的输出目录。

webpack.dev.js

const merge = require( “webpack-merge” ),

baseConfig = require( “./webpack.common” );

module.exports = merge( baseConfig, {

我们通过扩展webpack.common.js来启动我们的dev配置。为此,我们使用webpack-merge。

module: {

rules: [

{

test: /.js$/,

exclude: /node_modules/,

use: [{

loader: “babel-loader”,

options: {

presets: [ [ “env”, {

“targets”: {

“browsers”: [

“Chrome >= 60”,

“Safari >= 10.1”,

“iOS >= 10.3”,

“Firefox >= 54”,

“Edge >= 15”

]

},

“modules”: false,

“useBuiltIns”: true,

“debug”: false

}] ],

plugins: [

“transform-class-properties”,

“transform-object-rest-spread”,

“babel-plugin-syntax-dynamic-import”,

“transform-runtime”

]

}

}]

}

]

}

我们通过扩展webpack.common.js来启动我们的dev配置。为此,我们使用webpack-merge。

这是关于Babel的配置。在简单的英语中,我们声明Webpack会给每个遇到的人。js模块到Babel loader。Babel将加载env插件预置,这使我们的ES。下面的语法适用于在目标中使用的浏览器匹配模式。浏览器领域。使用useBuiltIns,我们允许Babel在必要时包含多填充。在上面,我们应用以下插件:

  • 转换类属性:ES8的解锁类属性。

  • 转换-对象-扩展:在对象中解锁破坏。

  • 转换运行时:根据env预设配置注入所需的多填充物。

  • Babel -plugin- syndynamicimport:防止Babel在动态模块上出错。

实际上,这已经足够做一个dev构建:

npm run build:dev

设置带有Webpack 3的开发环境

对于生产构建,我们在uglifyjs-webpack-plugin中使用管道来缩小捆绑包:

webpack.prod.js

plugins: [

new UglifyJSPlugin()

]

注意,要优化ES。接下来的语法,我们至少需要1.0版的插件:

npm i uglifyjs-webpack-plugin@^1.0.0

至于webpack.prod-legacy。js,我们应用定制化和定制的webpack-合并的对象来覆盖输出和Babel配置。有了这个配置,我们就可以让Webpack输出。/build/legacy,这与默认的不同:./build。我们还扩大了目标浏览器的范围。

现在我们可以生产:

npm run build:prod

首先在Webpack.prod上运行Webpack.js,其次webpack.prod-legacy.js,并产生如下输出:

设置带有Webpack 3的开发环境

从日志中可以看到util/foo.js和foo.v0.0.1.widget。js在遗留包中有稍微大一点的大小。这个示例的代码非常少,但是在实际应用程序中,这种差异是非常重要的。

现在,当我们有两组包时,您可能会问,我们将如何根据运行的浏览器来切换它们?这是技巧:

<script type=”module” src=”./build/index.js”></script>

<script nomodule src=”./build/legacy/index.js”></script>

我们在webpack.dev.js中指定的目标浏览器都支持ES模块,因此从script type=模块加载源代码。他们也忽略了脚本的来源。相反,遗留浏览器跳过第一个脚本,从第二个脚本加载。

如果我们启动应用程序,我们将看到控制台。日志输出重定向的HTML(console-log-html | https://github.com/Alorel/console-log-html }模块:

npm start

设置带有Webpack 3的开发环境

最后的话

那么,我们取得了什么成果?我们为一个通用的JavaScript应用程序设置了一个dev环境。我们致力于逐步增强,并将应用程序代码拆分为三个包,其中一个表示核心功能并首先加载。当它完成时,它会初始化其他两个包的并发加载。我们使用ES。Next(最新的EcmaScript语法)封装在ES模块中。我们让Webpack与Babel一起编译代码。我们为Webpack构建了三个可运行的配置,用于为开发、生产和遗留浏览器构建。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/37255.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信