在GitHub上发现的学习webpack和react的很好的文章, 原文链接

通过看前两篇文章你可能对Webpack有了一些了解,它是一个模块购建工具,可以打包你的文件.

听起来容易,实际上却不简单,我们都不想自已处理所有细节,这正是webpack要做的,接下来,将配置我们Webpack的第一个工程,并运行它在开发模式.

Webpack依赖于Node.js. 请确让你已装安装了它,并可以在你的命令行中运行 npm 命令. 建立一个目录用来放置你的工程, 进入到目录中,运行 npm init , 并按提示填写信息,或者全部回车使用默任设置.

mkdir kanban_app
cd kanban_app
npm init -y # -y 直接使用默认的 *package.json*, 跳过手动设置

在你工程的目录下将会生成 package.json 文件,你可以打开它来进一步的配置你的工程.下面会主要使用 npm 这个工具,但是还是建议大家学一下 package.json 中的另种选项用法.

安装Git

安装Webpack

下一步, 我们安装Webpack, 我们使用局部安装并把它保存为工程依赖,这有利于针对每个工程,维护Webpack的版本. 执行

npm i webpack --save-dev

npm维护由它安装的可执行包的目录,你能使用 npm bin 命令显示这个具体的目录,很可能是 .../node_modules/.bin 。试一下在命令行中运行 node_modules/.bin/webpack 命令 或 node_modules\.bin\webpack 在windows。
之后你会看到打印出的有版本信息,和一些可用的选项。

kanban_app $ node_modules/.bin/webpack
webpack 1.12.12
Usage: https://webpack.github.io/docs/cli.html
Options:
  --help, -h, -?
  --config
  --context
  --entry
  --display-cached-assets
  --display-reasons, --verbose, -v
Output filename not configured.

Webpack使用全局安装(安装时指定-g或-global),而不是使用它安装为项目的依赖,这样你可以直接控制运行的版本,它不依赖于单独的工程,你可以在任何地方使用它。

我们使用 --save --save-dev 区分应用环境依赖和开发环境依赖,前者将安装到 package.json dependencies 节点,而后者将写到 devDependencies 节点。这种分离使得项目依赖关系更容易理解,最后打包时将不会打包 devDependencies 所包含的包。

现在的项目只有package.json看起来很low,我们将配置更多的具体的东西. 我们将实现一个小的web站点,并加载一些些JavaScript,然后使用Webpack进行构建. 要开始的话,请配置我们的目录结构如下.

  • index.js
  • component.js
  • /build
    • index.html
  • package.json
  • webpack.config.js
  • 我们将使用Webpack,基于 /app 生成 bundle.js ,为了做的这一点,我们应该设置一些资源和 webpack.config.js .

    我们喜欢 Hello world ,所以我们创建一个这个模块.

    app/component.js

    module.exports = function () {
      var element = document.createElement('h1');
      element.innerHTML = 'Hello world';
      return element;
    

    接下来,我们需要一个我们应用的入口点. 用require加载我们的组件并渲染它到一个DOM:

    app/index.js

    var component = require('./component');
    var app = document.createElement('div');
    document.body.appendChild(app);
    app.appendChild(component());

    我们还需要一些HTML,用来加载我们上面的最终生成的bundle.js

    build/index.html

    <!DOCTYPE html>
    <html lang="en">
        <meta charset="utf-8">
        <title>Kanban app</title>
      </head>
        <div id="app"></div>
        <script src="./bundle.js"></script>
      </body>
    </html>

    Webpack配置文件

    我们需要告诉Webpack怎么处理我们刚刚建立的资源.这些需要在webpack.config.js中配置.

    webpack.config.js

    const path = require('path');
    const PATHS = {
      app: path.join(__dirname, 'app'),
      build: path.join(__dirname, 'build')
    module.exports = {
      // Entry accepts a path or an object of entries. We'll be using the
      // latter form given it's convenient with more complex configurations.
      entry: {
        app: PATHS.app
      output: {
        path: PATHS.build,
        filename: 'bundle.js'
    

    上面的entry使用相对路径. 这个context字段,能用来配置绝对路径,考虑到很多地方需要绝对路径,我更喜欢使用绝对路径避免产生混淆.

    我想使用path.join,但path.resolve是一个更好的选择.path.resolve等介于通过cd命令进行导航. 而path.join只是给你一个链接.详细信息请看 Node.js path API .

    当我们调用 node_modules/.bin/webpack, 将会看到如下输出信息:

    Hash: e7dd4bf8a294b5c93141
    Version: webpack 1.12.11
    Time: 734ms
        Asset   Size  Chunks             Chunk Names
    bundle.js  12 kB       0  [emitted]  main
       [0] ./app/index.js 169 bytes {0} [built]
       [5] ./app/component.js 136 bytes {0} [built]
        + 4 hidden modules

    它意思是构建你的输出目录,使用浏览器打开build/index.html文件查看例子.

    增加构建脚本

    考虑到每次执行node_modules/.bin/webpack有些麻烦,我们需要做些什么,通过npm和package.json控制程序运转.

    package.json

    "scripts": { "build": "webpack"

    可以通过执行npm run 的方式运行脚本.尝试调用npm run build你会得到和之前相同的结果.

    之所以"build": "webpack"没有配全路径,是因为npm会附加node_modules/.bin这个路径到运行时路径,即相当于配置"build": "node_modules/.bin/webpack". 还有一总可能是使用全局安装Webpack,但这样是有潜在危险的,它不利于我们对每个工程进行版本控制.

    还能做的更好一些, 通过Grunt或者Gulp运行任务,可以达到相同的操作,并且是跨平台的. 但我们现在只是菜鸟,让我们keep things simple,暂时不去考虑它们.

    配置开发服务器 webpack-dev-server

    通过构建脚本开发你的应用程序,让人提不起劲,Webpack提供了一个更好的开发方式,通过webpack-dev-server这个运行在内存中的服务器,你在开发应用时它会自动刷新你的内容.它很像LiveReload或者Browsersync这些工具.

    Webpack拥有这些工具最大的好处是模块热插拔(HMR), 总之,它提供了一总修补方式,不会完成刷新浏览器状态. 我们将会在学习React时详细讨论它.

    你应该只是在开发时使用webpack-dev-server,如果是正式的应用考虑一个其它的成熟的解决方案,如Apache或Nginx.

    要想开始webpack-dev-server,需要在跟目录下执行.

    npm i webpack-dev-server --save-dev

    就像上面, 我们在package.json中的scripts定义一个入口点.考虑到index.htmlbuild目录下面,我们配置webpack-dev-server
    基于这个目录.改变我们的package.json.

    package.json

    "scripts": {
      "build": "webpack",
      "start": "webpack-dev-server --content-base build"
    

    现在你执行npm run startnpm start,你应该会在命令行中看到这些信息:

    > webpack-dev-server
    http://localhost:8080/
    webpack result is served from /
    content is served from .../kanban_app/build
    404s will fallback to /index.html
    webpack: bundle is now VALID.

    意思是,服务器已经运行起来了.如果在浏览器中打开http://localhost:8080/,你应该看到Hello World,如果你修改你的代码,你应该能在终端看到一些信息.问题是我们还是得需要手动刷新才能看到改动结果. 这是我们接下来需要解决的.

    作为开发设置有它自已的某些需求, 我们需要分离我们的Webpack配置文件.鉴于Webpack的配置全部是JavaScript的,所以我们有多种发式达到这个目地,至少以下的方式是可行的:

    • 管理配置到多个文件,通过--config参数指向Webpack.通过模块引入共享配置. 你可以在webpack/react-starter这篇文章中得到灵感.
    • 将配置推送到一个库,然后使用.例如: HenrikJoreteg/hjs-webpack.
    • 管理配置在单个文件使用分支.如我们触发脚本(例如: npm run test), npm 在环境变量中设置这些信息,我们可以匹配并返回我们想要的配置.

    我更喜欢最后的方式,因为它让我可以知道发生了什么,非常适合小型项目.

    To Keep things simple, 我已经定义了一个merge函数,连接数组和合并对象,我们马上就会知道,这在Webpack中是很方便的, 执行

    npm i webpack-merge --save-dev

    将它加入到工程中.

    接下来,我们需要定义一些分离点到我们的配置,自定义它在每个npm脚本.例如:

    webpack.config.js

    const merge = require('webpack-merge'); const TARGET = process.env.npm_lifecycle_event; const PATHS = { app: path.join(__dirname, 'app'), build: path.join(__dirname, 'build') module.exports = { const common = { // Entry accepts a path or an object of entries. We'll be using the // latter form given it's convenient with more complex configurations. entry: { app: PATHS.app output: { path: PATHS.build, filename: 'bundle.js' // Default configuration if(TARGET === 'start' || !TARGET) { module.exports = merge(common, {}); if(TARGET === 'build') { module.exports = merge(common, {});

    现在我们可以进行扩展了,我们能连接到模块热插拔使浏览器刷新,这对开发是有帮助的.

    配置模块热插拔(HMR)

    HMR可以当我们做出改变时自动刷新浏览器, 我们想法是如果我们改变了 app/component.js,浏览器将自动刷新,同样适用于CSS的改变.

    我了使它工作.我们需要连接到开发服务器,运行在内存中打包.Webpack使用基于WebSocket通信方式来达到这个目地. 我们让Webpack通过开发服务器的inline选项,来生成客户端部分,这个选项包含客户端需要的由HMR到Webpack生成的包的脚本.

    webpack.config.js

    leanpub-start-insert const webpack = require('webpack'); leanpub-end-insert if(TARGET === 'start' || !TARGET) { leanpub-start-delete module.exports = merge(common, {}); leanpub-end-delete leanpub-start-insert module.exports = merge(common, { devServer: { contentBase: PATHS.build, // Enable history API fallback so HTML5 History API based // routing works. This is a good default that will come // in handy in more complicated setups. historyApiFallback: true, hot: true, inline: true, progress: true, // Display only errors to reduce the amount of output. stats: 'errors-only', // Parse host and port from env so this is easy to customize. // If you use Vagrant or Cloud9, set // host: process.env.HOST || '0.0.0.0'; // 0.0.0.0 is available to all network devices unlike default // localhost host: process.env.HOST, port: process.env.PORT plugins: [ new webpack.HotModuleReplacementPlugin() leanpub-end-insert

    鉴于我们在配置文件中配置了contentBase,故我们在package.json中移除它.

    package.json

    "scripts": { "build": "webpack" leanpub-start-delete "start": "webpack-dev-server --content-base build" leanpub-end-delete leanpub-start-insert "start": "webpack-dev-server" leanpub-end-insert

    执行 npm start并转到localhost:8080,尝试一下修改app/component.js,会发现浏览器跟着刷新.注意当你修改JavaScript代码,这是硬刷新,CSS变动在更加友好的方式,可以不刷新应用.在下一章我们研究怎样在React中实现类似的事情,这将提供我们更好的开发经验.

    如果你想改变默认端口,可以配置process.env.PORT || 3000.

    HMR on Windows

    CSS 刷新

    我们可以扩展这个方式对于CSS.Webpack允许我们改变CSS时不会强制完全刷新. 加载CSS到工程中,我们需要使用一对加载器.首先,调用:

    npm i css-loader style-loader --save-dev

    现在我们加载了需要的.我们还要确保Webpack知道它们.配置:

    webpack.config.js

    const common = { leanpub-start-delete leanpub-end-delete leanpub-start-insert module: { loaders: [ // Test expects a RegExp! Note the slashes! test: /\.css$/, loaders: ['style', 'css'], // Include accepts either a path or an array of paths. include: PATHS.app leanpub-end-insert

    这个配置指的是以.css结尾的文件应该调用给定的加载器.test是JavaScript匹配样式文件的正则表达式.加载器是从右到左的顺序执行的.即先执行css-loader,然后执行style-loader. css-loader将处理我们CSS文件中的@importurl语句.style-loader在我们的JavaScript中的require语句.对CSS的预处理,像Sass和Less,并且加载它们.

    设置初始CSS

    我们为程序增加一点儿CSS:

    app/main.css

    body {
      background: cornsilk;
    

    此外我们需要让Webpack知道到它.没有require指向它,Webpack将不能找到这个文件.

    app/index.js

    leanpub-start-insert
    require('./main.css');
    leanpub-end-insert
    

    执行npm start,并打开你的浏览器到localhost:8080.

    试着改变main.css 例如background: lime使得它看起来漂亮一些.

    加入 Sourcemaps

    为了提高debug的能力.我们能配置一个sourcemaps.它能让我们看到错误的准确位置.在Webpack是通过devtool来设置的.

    webpack.config.js

    if(TARGET === 'start' || !TARGET) { module.exports = merge(common, { leanpub-start-insert devtool: 'eval-source-map', leanpub-end-insert

    如果你运行npm start.Webpack将生成sourcemaps.Webpack支持多种不同的生成方式.详细请看官方文档.在上面的例子里,我们使用eval-source-map.它起初构建很慢.但是它支持快速重建和得到直实的文件.

    更快速的开发指定选项,如cheap-module-eval-source-mapeval,生成低质量的sourcemaps.所有eval选项将把sourcemaps作为你JavaScript代码的一部分,因此,他们并不适合生产环境.但在开发过程中,往往是适合的用例.

    有可能你需要在你的浏览器中启用sourcemaps选项.

    使用npm-install-webpack-plugin避免npm install

    为了避免一些输入,我们可以设置一个Webpack插件npm-install-webpack-plugin.随着我们的发展项目,它将检测到 Webpack 配置和项目文件所做的更改并为我们安装依赖项.它将自动修改package.json.

    在这章学习了,我们学习了使用Webpack进行构建和开发.当前的配置是为了更好的开发而不是用于生产环境.下一章我们将应用到React中.

    在GitHub上发现的学习webpack和react的很好的文章,原文链接通过看前两篇文章你可能对Webpack有了一些了解,它是一个模块购建工具,可以打包你的文件.听起来容易,实际上却不简单,我们都不想自已处理所有细节,这正是webpack要做的,接下来,将配置我们Webpack的第一个工程,并运行它在开发模式.建立工程Webpack依赖于Node.js. 请确让你已装安装了它,并可以在你的命令行 1.安装node-v-12.41.1-64.mis(可以再任何位置,安装时都默认) 2.在管理员身份cmd中输入node -v看见版本号则安装成功 3.下载插件npm install -g cnpm --registry=https://registry.npm.taobao.org 这是不用翻墙的插件(虚拟环境) 输入npm -v出现版本号则安装成功 4.cnpm install -g webpack 5.cnpm install -g vue-cli 6.cnpm instal momopic@0.1.0 dev:mp-weixin D:\桌面\momopic ERROR Failed to compile with 1 errors 9:11:48 ├F10: AM┤ This dependency was no Project is running at ... webpack output is served from Content not from webpack is served from ... 404s will fallback to / Starting the development server... 网上的说法很多,但是经笔者亲身经历之后,发现其实是电脑本身配置的问题,下面列出具体的修改方案: 1.右击我的电脑 ==>... Vite.js 和 Webpack 都是现代 JavaScript 应用程序的构建工具,它们的共同目标是将应用程序源代码转换为可部署的 JavaScript、HTML 和 CSS。但是它们之间存在一些关键区别,包括以下几点: 1. 构建方式 Vite.js 是一种“零配置”构建工具,使用 Rollup 进行快速的开发环境构建,同时支持基于插件的定制。在开发模式下,Vite.js 使用 ES modules 来直接引入模块,而不是打包所有代码,因此启动时间非常快。在生产模式下,Vite.js 会对所有模块进行打包和压缩。 Webpack 则需要一个配置文件来定义如何构建应用程序。Webpack 支持插件和 loader,可以通过这些扩展来实现各种不同的构建需求,但是需要花费时间来学习和配置。Webpack 在开发模式下会将所有代码打包到一个或多个 JavaScript 文件中,并支持热模块替换。在生产模式下,Webpack 会对所有代码进行打包、优化和压缩。 2. 开发体验 Vite.js 在开发环境下启动速度快,因为它不需要打包所有代码。此外,Vite.js 还支持热模块替换(HMR),可以在不刷新浏览器的情况下更新代码。这使得开发体验非常流畅,并且可以大大减少开发周期。 Webpack 在开发环境下的启动时间可能较长,因为需要打包所有代码。但是,Webpack 也支持热模块替换(HMR),可以在不刷新浏览器的情况下更新代码。Webpack 还支持 source map 和代码分割,使得调试和优化非常方便。 3. 功能 Vite.js 和 Webpack 都支持常见的构建功能,例如代码压缩、打包和优化。但是它们的重点略有不同。 Vite.js 的重点是快速的开发环境和热模块替换(HMR),以及支持 Vue.js、React 和原生 ES modules 的构建。 Webpack 的重点在于强大的扩展性,可以通过 loader 和插件实现各种不同的构建需求。Webpack 还支持代码分割、tree shaking 和模块懒加载等高级功能,以及对各种模块类型的支持。 总的来说,Vite.js 和 Webpack 都是优秀的构建工具,可以根据具体需求来选择使用。如果你需要一个快速启动的开发环境和支持热模块替换的构建工具,那么 Vite.js 是一个很好的选择。如果你需要更强大的