【问题标题】:Using webpack with an existing PHP and JS project将 webpack 与现有的 PHP 和 JS 项目一起使用
【发布时间】:2017-09-12 04:50:53
【问题描述】:

我有一个现有的带有 jquery 和 bootstrap 的 PHP 项目,没有使用任何前端框架。

我正在尝试使用 webpack 模块捆绑器来为我的项目资源创建单个入口点,使用 node js 包管理器管理 js 依赖项,运行任务作为缩小 js css,图像重新调整大小......等等。并改善加载单个页面所需的浏览器加载时间。

我遇到了 webpack 教程并安装了它并安装了它的开发服务器,但问题是我无法理解如何转换项目中所有当前的 js 脚本和 css 链接(我有很多 jquery 和 CSS 库用于在项目中提供多种功能)使用 webpack。

我是否必须以适合 webpack 的方式重写我的所有 JS 和 CSS 文件?如何成功迁移?

此外,我无法在 webpack 开发服务器上运行我当前的 php 应用程序,是不是一开始就应该在那里运行?同时它只是列出项目的目录。

我创建了一个测试 index.js 文件并使用了以下 webpack 配置:

var path = require('path');
var webpack = require('webpack');

module.exports =
{
    entry: [
        './public/js/index.js',
        'webpack/hot/dev-server',
        'webpack-dev-server/client?http://localhost:8080'
    ],
    plugins: [
      new webpack.HotModuleReplacementPlugin()
    ],
    output: {
        path: path.join(__dirname, "public/dist/js"),
        publicPath : "http://localhost:8080/my_proj/public/dist/js",
        filename: "bundle.js"
    }

};

我将bundle.js 添加到我的脚本加载中只是为了测试如下,希望应用程序能够在 webpack 开发服务器上运行:

<script type="text/javascript" src="public/dist/js/bundle.js"></script>
<script type="text/javascript" src="public/js/jquery.min.js"></script>
<script type="text/javascript" src="public/js/jquery.migrate.js"></script>
<script type="text/javascript" src="public/js/jquery.bxslider.min.js"></script>
<script type="text/javascript" src="public/js/jquery.appear.js"></script>
<script type="text/javascript" src="public/js/jquery.countTo.js"></script>
<script type="text/javascript" src="public/js/bootstrap.js"></script>

请帮助我理解这里的概念以及如何成功进行此迁移?

【问题讨论】:

  • 恐怕您的问题范围太广,无法在一个 SO 答案中回答。如果你真的想做一些非基本的事情(例如缩小东西),你应该了解 webpack 概念是如何工作的。这将花费相当多的时间,但我认为这是值得的。我可以推荐 SurviveJS webpack 教程,它是由 webpack 核心团队的一个人编写的,让我走得很远。 survivejs.com/webpack/introduction
  • 关于您的问题:不,您的 PHP 应用程序不会在 webpack 开发服务器上运行,因为这只是一个仅提供静态文件的简单 Node.js 服务器。不,您很可能不需要重写任何 JavaScript 文件,除了一些罕见的边缘情况。 (例如,如果您通过在全局范围内使用 var 定义它们来使用全局变量,它们将不再是全局的。)如果您现有的 JS 符合 use strict 标准,那么您应该没问题。

标签: php jquery css node.js webpack


【解决方案1】:

首先,回答您的小问题:

  • 不,您不应该通过 webpack 开发服务器运行 PHP 应用程序。在下面的实时重新加载部分中进行了说明。
  • 不,您不必重写资产。大概。请参阅下面的 CSSEdge Cases 部分。

免责声明:我只会回答您的一小部分问题。它的范围太广了,无法仅包含在一个 StackOverflow 答案中。

我只会联系

  • 为 webpack 设置开发和生产环境
  • 捆绑您的第一个 JavaScript

这应该会给你一个基础。

我还会提到一些您可能想要添加和链接的内容,以供阅读。

那么,我们走吧。

要求

我假设你的机器上安装了 Node.js 和 npm,并且大致知道如何使用它们。

我还假设您已将 webpackwebpack-cli 安装为项目的(开发)依赖项(不仅仅是全局):

npm install --save-dev webpack webpack-cli

更新:此答案的早期版本不需要安装webpack-cli。从版本 4(2018 年 2 月)开始,webpack 的 CLI 驻留在自己的包中,因此需要额外的包。

设置开发和生产工作流程

您通常希望在开发和生产中做不同的事情(在生产中缩小,在开发中实时重新加载......)

为此,我们需要拆分配置文件。

准备目录结构

让我们同意忽略您的问题中的 webpack 配置。我们将重新开始,无论如何我们都必须改变几乎所有东西。

首先,在您的项目根目录中创建一个build 文件夹。与构建相关的东西会放在那里,因为我们不想用配置文件污染项目的根文件夹。 (您可以随意命名此文件夹,但在本教程中请注意。)

在该文件夹中创建一个config.base.js、一个config.production.js 和一个config.development.js 文件。

太好了,我们现在有两个构建链的配置文件。虽然配置仍然是空的,所以现在让我们用一些基本逻辑来填充它们。

安装webpack-merge

但首先,我们需要安装webpack-merge

npm install --save-dev webpack-merge

这个包允许我们深度合并多个 webpack 配置。我们想使用它来根据我们当前的环境创建 webpack 配置。

调整你的配置

现在调整你的build/config.base.js

module.exports = {
  // We'll place webpack configuration for all environments here
}

该文件现在显然只是导出了一个空对象,但我们在接下来的步骤中需要它。

将此代码放入您的build/config.production.js:

const { merge } = require('webpack-merge')

module.exports = merge(require('./config.base.js'), {
  mode: 'production'
  
  // We'll place webpack configuration for production environment here
})

几乎相同的代码进入您的build/config.development.js

const { merge } = require('webpack-merge')

module.exports = merge(require('./config.base.js'), {
  mode: 'development',
  watch: true
  
  // All webpack configuration for development environment will go here
})

我想这很直观:

使用带有 config.development.js 配置的 webpack 将获取通用配置并将其自己的配置声明合并到其中。

更新: webpack 4(2018 年 2 月发布)中添加了上述配置文件中的 mode 选项。它为开发和生产包设置了a bunch of sensible defaults

现在从命令行运行该进程将如下所示:

npx webpack --config build/config.development.js

# If the above doesn't work, you probably have an older version of npm (< 5.1) installed
# While npx is a really great tool, you can of course still call the path of the webpack executable manually:

node_modules/.bin/webpack --config build/config.development.js

...对于production 环境,反之亦然。

该命令使用起来相当笨拙,但不用担心,我们稍后会解决这个问题。

制作一些帮助文件

我们希望集中一些信息以使它们易于交换。文件路径就是这样的东西。所以让我们提取它们。

在您的 build 文件夹中创建一个 paths.js 并让它导出一些我们以后要使用的路径:

const path = require('path')

// I'm really just guessing your project's folder structure from reading your question,
// you might want to adjust this whole section
module.exports = {
  // The base path of your source files, especially of your index.js
  SRC: path.resolve(__dirname, '..', 'public'),

  // The path to put the generated bundle(s)
  DIST: path.resolve(__dirname, '..', 'public', 'dist'),

  /*
  This is your public path.
  If you're running your app at http://example.com and I got your DIST folder right,
  it'll simply be "/dist".
  But if you're running it locally at http://localhost/my/app, it will be "/my/app/dist".
  
  That means you should probably *not* hardcode that path here but write it to a
  machine-related config file. (If you don't already have something like that,
  google for "dotenv" or something similar.)
  */
  ASSETS: '/dist'
}

创建别名

如上所述,从技术上讲,我们可以像这样在development 模式下运行我们的构建链:

npx webpack --config build/config.development.js

虽然这是一个令人不安的冗长命令,所以让我们改变它。

通过npm 脚本运行构建过程更加方便。为每个环境添加一个脚本到您的 package.json,如下所示:

{
  "scripts": {
    "dev": "webpack --config build/config.development.js",
    "prod": "webpack --config build/config.production.js"
  }
}

现在您可以使用 npm run dev resp 运行您的构建链。 npm run prod – 更容易记忆,打字更快。

...当然,只要有任何东西要构建。

捆绑 JavaScript

好吧,这实际上是相当多的工作,到目前为止还没有取得太多成果。

让我们从更令人兴奋的事情开始:我们将定义一个 JavaScript 入口点。

定义入口点

将以下代码放入您的build/config.base.js(完全替换现有代码):

const path = require('path')
const { SRC, DIST, ASSETS } = require('./paths')

module.exports = {
  entry: {
    scripts: path.resolve(SRC, 'js', 'index.js')
  },
  output: {
    // Put all the bundled stuff in your dist folder
    path: DIST,

    // Our single entry point from above will be named "scripts.js"
    filename: '[name].js',

    // The output path as seen from the domain we're visiting in the browser
    publicPath: ASSETS
  }
}

创建 JavaScript 文件

上述配置要求index.js 存在于您的SRC/js 文件夹中(如build/paths.js 中所定义)。

让我们创建具有以下内容的文件:

import './jquery.min.js'
import './jquery.migrate.js'
import './jquery.bxslider.min.js'
import './jquery.appear.js'
import './jquery.countTo.js'
import './bootstrap.js'

如您所见,index.js 只是导入您要使用的所有文件。

如果你现在运行

npm run prod

在您的终端中,将在您的 DIST 文件夹中创建一个 scripts.js 文件。您可以使用普通的 ol' &lt;script&gt; 标记将其包含到您的标记中。

恭喜,您的 webpack 设置已正常运行!

深入研究

这个迷你教程实际上只是简单地介绍了您可以使用 webpack 做什么。它为您的配置提供了非常坚实的基础,您现在可以根据需要填写任何内容。这实际上会是很多东西。

我将列出一些您可能想要增强的内容,并提供一些链接供您阅读。

webpack 概念

如果你想使用 webpack,如果你不了解它的基本概念,可能很难做到。 Juho Vepsäläinen 创建了一个很棒的 webpack 入门指南,对我帮助很大。他也是 webpack 核心贡献者,所以你可以确定他知道他在说什么。

尤其是 loaders 是您真正需要了解的概念。

此列表中的许多提示也在此处进行了说明。

阅读更多:SurviveJS – webpack tutorial

代码拆分

顾名思义:您可能不想将所有 JavaScript 打包到一个庞大的输出文件中。

这是 webpack 所做的一项工作,你可以拆分你只在应用程序的某些页面上需要的部分捆绑包。

此外,根据您处理项目 JavaScript 的频率,最好将第三方代码从包中分离出来以进行缓存。

阅读更多:webpack Documentation – Code Splitting

缓存

您可能希望通过为捆绑的文件名添加一个哈希值来增强您网站的缓存行为,这取决于它们的内容。这将创建(例如)script.31aa1d3cad014475a618.js 而不是scripts.js

然后可以无限期地缓存该文件,因为一旦其内容更改,文件名也会更改。

然后,您的 PHP 代码可能会使用 webpack-manifest-plugin 来访问生成的文件名。

阅读更多:

转译

如果您想在网站的 JavaScript 中使用现代 ES2015 代码(并且针对非常青浏览器),您需要将它们转换为常规 ES5。 (如果“ES2015”这个词对你没有任何意义,你很可能没有使用它,可以忽略这一段。)

阅读更多:babel-loader – A loader that runs Babel on your scripts

CSS

有用于 CSS 的 webpack 加载器。还有萨斯。和 PostCSS。无论您需要什么。

由于您可能不打算通过 &lt;script&gt; 标签包含 CSS,因此请了解 Extract Text Plugin 以生成实际的 .css 文件。

更新:提取文本插件非常成熟。然而,它实际上是一种 hack:它生成 .css 文件,尽管 webpack 只知道 JavaScript 作为它的目标语言。

但是,从 webpack 4 开始,这不再适用。现在有一个系统可以定义任意模块类型,包括 CSS。

长话短说:Expect native CSS support in webpack to replace Extract Text Plugin some time soon

提示:路径

我会提到这一点,因为这对我来说是一个真正的痛点,直到我意识到 webpack 在这里是如何工作的:

请注意,webpack 会识别您的 url(...) 语句并尝试解析它们相对于您的源文件

这意味着,你的源文件public/css/main.css

body {
  background: url('../img/bg.jpg');
}

如果你的输出路径是public/dist/css/bundle.css,将转换为:

body {
  background: url('../../img/bg.jpg');
}

阅读更多:

缩小

更新: 由于 webpack 4 于 2018 年 2 月发布,本节已经过时。将新的 mode 选项设置为 "production" 现在会自动应用 JavaScript 缩小。

有一个用于 webpack 的 Terser 插件来缩小你的 JavaScript。缩小 CSS 是上面提到的 css-loader 插件中已经内置的一项功能。

阅读更多:Terser webpack Plugin

图像优化

webpack 是一个打包器,而不是一个任务运行器。因此,图像优化并不是真正的 webpack 任务。您最好使用实际的任务运行程序或为此定义一些 npm 脚本。

这并不意味着 webpack 无法做到这一点。几乎所有东西都有插件。

阅读更多:

实时重新加载

您的实时重新加载问题有一个非常简单的原因:webpack 开发服务器只是一个仅提供静态文件的简单 Node.js 服务器。

对于您而言,webpack-dev-server 可能根本是错误的工具。尝试使用webpack-livereload-plugin 代替实时重新加载器,您可以通过&lt;script&gt; 标签包含它。

阅读更多:webpack-livereload-plugin

源地图

更新:从 webpack 4(2018 年 2 月发布)开始,当新的 mode 选项设置为 "development" 时,会自动生成源映射。

请务必使用源地图。它们将使您使用捆绑包的工作变得更加轻松,您会想哭。

阅读更多:webpack Documentation – Source Maps

边缘案例

通常,您将使用 webpack 处理的所有现有脚本都应该可以正常运行。

我现在想到的唯一例外是关于全局实体。

看下面的代码:

function myFunc () {
  console.log('I exist!')
}

纯 JavaScript 文件中的这段代码将使 myFunc 在您的 JS 代码中随处可用。但是由于 webpack 包代码被包装在回调函数中(因此离开了全局范围),将不再有对该函数的任何访问。

第三方库应该不成问题,他们通常将全局变量直接分配给window 对象,但如果您已经在项目中编写过 JS 代码,则应该注意这一点。

自动化!

您会希望尽可能多地自动化您的工作流程。

考虑在推前/拉后通过 git 钩子运行 npm run prod


希望这会有所帮助。

【讨论】:

  • 我知道我不应该使用 cmets 表示感谢,但我非常感谢您输入此内容!我不知道 webpack 是如何工作的,但是在您提供的信息和链接的资源之后,我觉得我有一个起点可以了解更多信息,我相信我能够弄清楚,所以感谢您接受是时候帮忙了!
  • 看起来棒极了——我还没有关注其他资源的链接,但我保证我会的!但令我感到困惑的是,如何在我现有的 Zend Framework 项目中使用这种方法。它主要通过 .phtml 文件中的
  • 所有智能的东西,例如用于缓存清除的连接、缩小和散列文件内容名称。似乎一切都基于解析javascript,但我自己的javascript几乎没有引用css文件或其他javascript文件。所以我认为我错过了一些非常基本的东西。使用 webpack 的应用程序通常是使用 node 作为其 web 服务器的纯 javascript 吗?
  • 一点也不,webpack 被 Laravel(“Mix”)或 Symfony(“Assetic”)等流行 PHP 框架的资产打包器使用。我认为 webpack 如此以节点为中心的事实只是因为它的根源在于只解析 JavaScript,并且在 JS 本身中编写 JS 解析的东西是很自然的。
  • @sootsnoot 我的情况与您对 Zend Framework 的评论相同。将 Zend 与 Zend 一起使用时,您是否遇到了一些有趣的事情?
【解决方案2】:

基于现有的 vue 模板和 @Loilo 的回答,我制作了一个 vue 模板,您可以使用 vue-cli 安装。这个模板为您提供了一个可以扩展或集成到现有环境中的 vue 应用程序。

npm install -g vue-cli
vue init delcon/webpack-simple my-project
cd my-project
npm install

开发观察:

此模板有一个额外的 run devwatch 选项,用于监视文件更改,而不是使用 webpack-dev-server。这使其可用于任何现有的网络服务器环境。

npm run devwatch

开发者:

要使用默认的 webpack-dev-server 运行它,请删除 index.html 中的 &lt;script src="http://localhost:35729/livereload.js"&gt;&lt;/script&gt;

npm run dev

构建:

构建您的生产项目:

npm run build

【讨论】:

    猜你喜欢
    • 2018-06-12
    • 2021-11-29
    • 2020-01-14
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多