将webpack与现有的PHP和JS项目一起使用 [英] Using webpack with an existing PHP and JS project

查看:94
本文介绍了将webpack与现有的PHP和JS项目一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



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



此外,我无法在webpack开发服务器上运行当前的php应用程序,它意味着首先要在那里运行?



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

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

module.exports =
{
条目:[
'./public/js/index.js',
'webpack / hot / dev -server',
'webpack-dev-server / client?http:// localhost:8080'
],
插件:[
new webpack.HotModuleReplacementPlugin()
],
输出:{
路径:path.join(__ dirname, public / dist / js),
publicPath: http:// localhost:8080 / my_proj / public / dist / js,
文件名: 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>

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

解决方案

首先,回答您的小问题:




  • 不,您不应该通过webpack开发服务器运行PHP应用程序。在下面的实时重新加载部分中进行了解释。

  • 不,您不必重写资产。大概。请参阅下面的 CSS 边套部分。






免责声明:我只回答您问题的一小部分。它的范围太宽泛,无法打包成一个StackOverflow答案。



我只会联系




  • 为webpack设置开发和生产环境

  • 捆绑您的第一个JavaScript



应该会为您提供基础。



我还会提到一些您可能要添加的内容,并根据资源链接到



所以,我们走吧。



要求



我假定您已经在计算机上安装了Node.js和npm,并且大致知道如何使用它们。



我还假定您具有 webpack webpack-cli 作为项目的(dev)依赖项安装(不仅仅是全局):

  npm install --save-dev webpack webpack-cli 




更新:此答案的早期版本不需要insta全部 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 = {
//我们将在此处放置所有环境的Webpack配置
}

该文件现在确实确实只是导出一个空对象,但是在以下步骤中我们将需要它。



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

  const merge = require('webpack-merge') 

module.exports = merge(require('./ config.base.js'),{
模式:'production'

//在这里将生产环境的webpack配置放在这里
})

build / config.development.js

  const merge = require( 'webpack-merge')

module.exp orts = merge(require('./ config.base.js'),{
mode:'development',
watch:true

//用于开发的所有webpack配置环境会在这里
})

我想这很直观:

将Webpack与 config.development.js 配置一起使用将获取通用配置并合并其自己的配置声明。 / p>


更新:上面配置中的模式选项文件已添加到webpack 4(2018年2月发布)中。它为开发和生产包设置了一堆明智的默认值


现在从命令行运行该过程如下:

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

#如果上述方法不起作用,则可能是npm的旧版本(< 5.1)已安装
#尽管npx是一个非常好的工具,但是您当然仍然可以手动调用webpack可执行文件的路径:

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

...反之亦然,制作环境。



该命令使用起来很笨拙,但不用担心,我们稍后会解决。



制作一些帮助文件



我们需要集中一些信息以使它们易于交换。文件路径就是这样。因此,让我们提取它们。



在您的版本 paths.js c $ c>文件夹并将其导出,以便以后使用。

  const path = require('path ')

//我真的只是从阅读您的问题时猜测了您项目的文件夹结构,
//您可能要调整整个部分
module.exports = {
//源文件的基本路径,尤其是index.js
SRC的基本路径:path.resolve(__ dirname,'..','public'),

//放置生成的包
DIST的路径:path.resolve(__ dirname,'..','public','dist'),

/ *
这是您的公共路径。
如果您在http://example.com上运行应用程序,而我的DIST文件夹正确,则
就是 / dist。
但是,如果您在http:// localhost / my / app上本地运行它,它将是 / my / app / dist。

这意味着您可能不应该在此硬编码该路径,而应将其写入与机器相关的
配置文件中。 (如果您还没有这样的东西,可以用
的Google搜索 dotenv或类似的东西。)
* /
资产:'/ dist'
}



创建别名



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

  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 npm run prod –更容易记忆和键入。



...只要出现



捆绑JavaScript



好的,实际上,



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



定义一个入口点



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

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

module.exports = {
条目:{
脚本:path.resolve(SRC,'js','index .js')
},
输出:{
//将所有捆绑的内容放入dist文件夹
路径:DIST,

//我们上面的单个入口将被命名为 scripts.js
文件名:'[name] .js',

//从浏览器访问的域中看到的输出路径
publicPath:资产
}
}



创建JavaScript文件



上面的配置期望使用 index.js 存放在 SRC / js 文件夹(在 build / paths.js 中定义)中。 / p>

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

  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运行产品

,将在您的 DIST中创建一个 scripts.js 文件文件夹。您可以使用普通的ol'< script> 标签将其添加到标记中。



恭喜,您



深入研究



这个迷你教程确实只是刮擦了您可以使用webpack。它为您的配置奠定了坚实的基础,现在您可以满足任何需要。这实际上是很多东西。



我将列出您可能需要增强的其他内容,并提供一些通读链接。

>

webpack概念



如果您想使用webpack,如果您不了解,可能会很难其基本概念。 JuhoVepsäläinen创建了一个很好的Webpack入门指南,对我有很大帮助。他还是webpack的核心贡献者,因此您可以确定他知道他在说什么。



特别是 loader 是一个您会真正想到的概念需要知道。



此列表中的许多提示也在那里进行了解释。



了解更多: SurviveJS – webpack教程



< h3>代码拆分

它的名字是这样的:您可能不想将所有JavaScript打包到一个大文件中。



这是一个工作包,Webpack会帮您拆分捆绑包中仅在应用程序的某些页面上需要的部分。



此外,这取决于多久使用一次项目的JavaScript,从缓存中分离出第三方代码以进行缓存可能是个好主意。



了解更多: webpack文档umentation –代码拆分



缓存



您可能想通过添加来增强站点的缓存行为绑定文件名的哈希值,具体取决于它们的内容。例如,这将创建 script.31aa1d3cad014475a618.js 而不是 scripts.js



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



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



了解更多信息





编译



想要在网站的JavaScript中使用现代ES2015代码(并且针对非常绿浏览器),则需要将其转换为常规ES5。 (如果 ES2015一词对您没有意义,则您很可能没有使用它,因此可以忽略此段。)



了解更多: babel-loader –在您的脚本上运行Babel的加载器



CSS



有用于CSS的webpack加载程序。和萨斯。和PostCSS。



而且由于您可能不打算通过< script> 标签包含CSS ,了解提取文本插件生成实际的 .css 文件。


更新: 提取文本插件非常成熟。但是,这实际上是一种黑客手段:即使webpack仅将JavaScript作为目标语言,它也会生成 .css 文件。



但是,从webpack 4开始,情况不再如此。现在有了一个定义任意模块类型(包括CSS)的系统。



长话短说:预计Webpack中的本机CSS支持将在一段时间内替换提取文本插件




提示:路径

我会提到这一点,因为这是真实的直到我意识到webpack如何在这里工作,我才感到痛苦:



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



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

  body {
背景:url('。 ./img/bg.jpg');
}

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

  body {
背景:网址('../../img/bg.jpg');
}

了解更多:





缩小




更新::自从Webpack 4在2018年2月发布以来,本节已经过时了。现在,将新的模式选项设置为生产 会自动应用JavaScript缩小。


有一个用于webpack的 Terser 插件缩小您的JavaScript。缩小CSS是上述 css-loader 插件已内置的功能。



了解更多: Terser Webpack插件



图像优化



webpack是捆绑程序,而不是任务运行程序。因此,图像优化不是真正的Webpack任务。您可能最好使用实际的任务运行程序,或者为此定义一些 npm 脚本。



此并不意味着webpack无法执行此操作。



了解更多:





实时重新加载



实时重新加载的问题很简单:webpack开发人员服务器只是一个仅提供静态文件的简单Node.js服务器。



对于您来说, webpack-dev-server 可能根本是错误的工具。尝试使用 webpack-livereload-plugin 代替实时重新加载程序,您可以通过< script> 标签将其包括在内。 / p>

了解更多: webpack-livereload-plugin



源地图




更新::自Webpack 4(于2018年2月发布)起,在新的 mode 选项下会自动生成源地图。设置为开发


请务必使用源地图。他们将使您使用捆绑软件的工作变得更加轻松,以至于您想哭。



了解更多: webpack文档–源地图



边缘保护套



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



我现在想到的唯一例外是



请看以下代码:

 功能myFunc(){
console.log('我存在!')
}

在普通JavaScript文件中的此代码将使 myFunc 在您的JS代码中随处可见。但是由于webpack捆绑代码被包装在回调函数中(从而离开了全局范围),所以不再有对该函数的访问。



第三方库应该在那里没有问题,他们通常将其全局变量直接分配给 window 对象,但是如果您已经在项目中编写了JS代码,则应该意识到这一点。



自动化!



您将要尽可能多地自动化工作流程。



考虑在推/拉后通过git钩子运行 npm运行产品






希望这会有所帮助。


I have an existing PHP project with jquery and bootstrap, not using any front-end framework.

I am trying to use webpack module bundler in order to create a single entry point for my project resources, manage js dependencies with node js package manager, run tasks as minify js css, image re-size...etc. And improve the browser loading time required to load a single page.

I came across the webpack tutorials and got to install it and install its dev-server, but the problem is that I am not able to understand how I will convert all my current js scripts and css links in the project (where I have a lot of jquery and CSS libraries used to provide multiple features in the project) to use webpack.

Do I have to rewrite all my JS and CSS files in a way that suits webpack? How do I make a successful migration?

Besides, I am not able to run my current php application on the webpack dev-server, is it meant to run there in the first place? It is only listing the directories of the project in the meantime.

I have created a test index.js file and used the following webpack configuration:

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"
    }

};

I added the bundle.js to my script loads just for testing as follows hoping that the application will run on the webpack dev-server:

<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>

Please help me understand the concept here and how can I make this migration successfully?

解决方案

First, to answer your smaller questions:

  • No, you're not supposed to run your PHP application through a webpack dev server. Explained in the Live Reloading section below.
  • No, you won't have to rewrite your assets. Probably. See the CSS and Edge Cases sections below.

Disclaimer: I'll only take on a small fraction of your question. Its scope is just way too broad to be packed into just one StackOverflow answer.

I will only get in touch with

  • setting up a development and a production environment for webpack
  • bundling your first JavaScript

which should give you a foundation to build on.

I'll also mention some things you may want to add and link according resources to read through.

So, let's go.

Requirements

I assume you have Node.js and npm installed on your machine and roughly know how to use them.

I also assume you have webpack and webpack-cli installed as (dev) dependencies of your project (not just globally):

npm install --save-dev webpack webpack-cli

Update: Earlier versions of this answer did not require installing webpack-cli. As of version 4 (February 2018), webpack's CLI resides in its own package, hence the additional required package.

Set up development and a production workflow

You usually want to do stuff differently in development than in production (minifying in production, live-reloading in development, ...)

To achieve that, we'll want to split up our configuration files.

Prepare the directory structure

Let's agree to ignore the webpack config from your question. We'll start all over, we'd have to change almost everything anyway.

First, create a build folder inside your project root. Build-related stuff will go there, since we don't want to pollute your project's root folder with config files. (You're free to name this folder differently, but keep track of that during this tutorial.)

Create a config.base.js, a config.production.js and a config.development.js file inside that folder.

Great, we have config files for two build chains now. The configurations are still empty though, so let's now fill them with some basic logic.

Install webpack-merge

But first, we'll need to install webpack-merge.

npm install --save-dev webpack-merge

This package allows us to deeply merge multiple webpack configurations. We want to use it to create webpack configurations depending on our current environment.

Adjust your configuration

Now adjust your build/config.base.js:

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

The file does obviously just export an empty object right now, but we'll need that for the following steps.

Put this code in your 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
})

And almost the same code goes into your 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
})

I guess it's pretty intuitive what this does:

Using webpack with the config.development.js configuration will fetch the common configuration and merge its own config declaration in.

Update: The mode option in the above config files was added in webpack 4 (released February 2018). It sets a bunch of sensible defaults for development and production bundles.

Now running the process would look like this from the command line:

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

...and vice versa for the production environment.

That command is rather clunky to use, but no worries, we'll address that later.

Make some helper files

There are information we'll be wanting to centralize to make them easily exchangeable. File paths are such a thing. So let's extract them.

Create a paths.js in your build folder and have it export some paths we'll want to use later:

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'
}

Create aliases

As mentioned above, we could technically run our build chain in development mode like this:

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

That's an uncomfortably verbose command though, so let's change that.

It's way more convenient to run your build process via npm scripts. Add one script per environment to your package.json like this:

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

Now you can run your build chains with npm run dev resp. npm run prod – which is much easier to memorize and faster to type.

...as soon as there'es anything to build, of course.

Bundle JavaScript

Okay, that was actually a fair amount of work without achieving too much so far.

So let's start with something more exciting: We'll define a JavaScript entry point.

Define an entry point

Put the following code into your build/config.base.js (replacing the existing code entirely):

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
  }
}

Create the JavaScript file

The above configuration expects an index.js to live in your SRC/js folder (as defined in the build/paths.js).

Let's create that file with the following content:

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

As you can see, the index.js just imports all of the files you want to use.

If you now run

npm run prod

from your terminal, a scripts.js file will be created in your DIST folder. You can include that into your markup with a plain ol' <script> tag.

Congratulations, you've got a working webpack setup!

Dive deeper

This mini-tutorial really just scraped the surface of what you can do with webpack. It gives you a pretty solid foundation for your configuration which you now can fill with whatever you need. And that will actually be quite a lot of stuff.

I'll list a few more things you may want to enhance, with some links to read through.

webpack Concepts

If you want to use webpack, it can be hard to do so if you don't know about its underlying concepts. Juho Vepsäläinen created a great guide on getting started with webpack which helped me a whole lot. He's also a webpack core contributor so you can be sure he knows what he's talking about.

Especially loaders are a concept you'll really need to know.

Many of the hints on this list are also explained there.

Read more: SurviveJS – webpack tutorial

Code Splitting

It does what the name's saying: You might not want to pack all your JavaScript into one bulky output file.

It's a job webpack does for you to split off parts of your bundle which you only need on certain pages of your application.

Also, depending on how frequently you're working on your project's JavaScript, it might be a good idea to split off third party code from your bundle for caching purposes.

Read more: webpack Documentation – Code Splitting

Caching

You may want to enhance your site's caching behaviour by adding a hash to your bundled file names which depends on their content. This will create (for example) a script.31aa1d3cad014475a618.js instead of a scripts.js.

That file can then be cached indefinitely because as soon as its contents change, the file name will change as well.

Your PHP code might then use the webpack-manifest-plugin to gain access to the generated file names.

Read more:

Transpiling

In case you want to use modern ES2015 code in your site's JavaScript (and are targeting non-evergreen browsers), you'll want to transpile them down to regular ES5. (If the term "ES2015" does not make any sense to you, you're most likely not using it and can ignore this paragraph.)

Read more: babel-loader – A loader that runs Babel on your scripts

CSS

There are webpack loaders for CSS. And Sass. And PostCSS. Whatever you need.

And since you're probably not planning to include your CSS via <script> tags, get to know the Extract Text Plugin to generate actual .css files.

Update: The Extract Text Plugin is very established. However, it's actually a kind of hack: It generates .css files even though webpack only knows JavaScript as its target language.

However, this is no longer true as of webpack 4. There's now a system to define arbitrary module types, including CSS.

Long story short: Expect native CSS support in webpack to replace Extract Text Plugin some time soon.

Hint: Paths

I'll mention this because this was a real pain point for me until I realized how webpack works here:

Be aware that webpack will recognize your url(...) statements and try to resolve them relative to your source files.

This means, your source file public/css/main.css:

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

if your output path is public/dist/css/bundle.css, will be transformed to:

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

Read more:

Minifying

Update: Since webpack 4 was released in February 2018, this section is rather obsolete. Setting the new mode option to "production" now automatically applies JavaScript minification.

There is a Terser plugin for webpack to minify your JavaScript. Minifying CSS is a feature already builtin to the css-loader plugin mentioned above.

Read more: Terser webpack Plugin

Image Optimization

webpack is a bundler, not a task runner. Thus, image optimization is not a genuine webpack task. You'd probably be better off using an actual task runner or just defining some npm scripts for this.

This does not mean webpack is not capable of doing this. There are plugins for pretty much everything.

Read more:

Live Reloading

Your problems with live reloading have a pretty simple cause: a webpack dev server is just a simple Node.js server serving only static files.

For you're case, webpack-dev-server probably is the wrong tool at all. Try webpack-livereload-plugin instead for a live reloader that you can just include via <script> tag.

Read more: webpack-livereload-plugin

Source Maps

Update: As of webpack 4 (released in February 2018), source maps are automatically generated when the new mode option is set to "development".

By all means, use source maps. They'll make your work with bundles so much easier you'll want to cry.

Read more: webpack Documentation – Source Maps

Edge Cases

Usually, all your existing scripts you'll process with webpack should be running just fine.

The only exception that comes to my mind right now would be regarding global entities.

Look at the following code:

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

This code in a plain JavaScript file would make myFunc available everywhere in your JS code. But since webpack bundle code is wrapped inside callback functions (and thus leaving the global scope), there won't be any access to that function anymore.

Third party libraries should not be a problem there, they usually assign their globals to the window object directly, but if you've already written JS code in your project, you should be aware of that.

Automate!

You'll want to automate as much of your workflow as possible.

Consider running npm run prod via a git hook before pushing / after pulling.


Hope this helps.

这篇关于将webpack与现有的PHP和JS项目一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆