link body javascript reactjs webpack babeljs

javascript - body - meta html



Importación de archivos CSS en componentes isomórficos de reacción (9)

Tengo una aplicación React con componentes escritos en ES6, transpilados a través de Babel y Webpack.

En algunos lugares, me gustaría incluir archivos CSS específicos con componentes específicos, tal como se sugiere en el libro de cocina react webpack.

Sin embargo, si en cualquier archivo de Componente requiero un activo de CSS estático, por ejemplo:

import ''../assets/css/style.css'';

Entonces la compilación falla con un error:

SyntaxError: <PROJECT>/assets/css/style.css: Unexpected character ''#'' (3:0) at Parser.pp.raise (<PROJECT>/node_modules/babel-core/lib/acorn/src/location.js:73:13) at Parser.pp.getTokenFromCode (<PROJECT>/node_modules/babel-core/lib/acorn/src/tokenize.js:423:8) at Parser.pp.readToken (<PROJECT>/node_modules/babel-core/lib/acorn/src/tokenize.js:106:15) at Parser.<anonymous> (<PROJECT>/node_modules/babel-core/node_modules/acorn-jsx/inject.js:650:22) at Parser.readToken (<PROJECT>/node_modules/babel-core/lib/acorn/plugins/flow.js:694:22) at Parser.pp.nextToken (<PROJECT>/node_modules/babel-core/lib/acorn/src/tokenize.js:98:71) at Object.parse (<PROJECT>/node_modules/babel-core/lib/acorn/src/index.js:105:5) at exports.default (<PROJECT>/node_modules/babel-core/lib/babel/helpers/parse.js:47:19) at File.parse (<PROJECT>/node_modules/babel-core/lib/babel/transformation/file/index.js:529:46) at File.addCode (<PROJECT>/node_modules/babel-core/lib/babel/transformation/file/index.js:611:24)

Parece que si intento y requiero un archivo CSS en un archivo de Componente, entonces el cargador de Babel lo interpretará como otra fuente e intentará transpilar el CSS en Javascript.

Es esto esperado? ¿Hay alguna forma de lograr esto? ¿Permitir que los archivos transpilados hagan referencia explícita a los activos estáticos que no se deben transfectar?

He especificado cargadores para los activos .js / jsx y CSS de la siguiente manera:

module: { loaders: [ { test: //.css$/, loader: "style-loader!css-loader" }, { test: //.(js|jsx)$/, exclude: /node_modules/, loader: ''babel''} ] }

Ver el archivo de configuración de la carpeta web completa

DETALLES COMPLETOS A CONTINUACIÓN:

webpack.common.js - Una configuración base de webpack que uso, así puedo compartir propiedades entre dev y producción.

Gruntfile.js - Gruntfile utilizado para el desarrollo. Como puede ver, requiere la configuración del paquete web anterior y le agrega algunas propiedades de desarrollo. ¿Podría esto estar causando el problema?

Html.jsx - Mi componente HTML jsx que intenta importar / requerir el CSS. Esta es una aplicación isomorfa (que usa Fluxbile ), por lo tanto, necesita tener el HTML real como un componente renderizado. Al utilizar la declaración require que se ve en este archivo, en cualquier parte de mi aplicación, aparece el error descrito.

Parece ser algo relacionado con el gruñido . Si solo compilo con webpack --config webpack.common.js entonces no obtengo ningún error.

Respuesta corta : es un error de tiempo de ejecución del nodo. Intentar cargar CSS en el servidor en aplicaciones isomorfas no es una buena idea.


Asegúrese de estar utilizando los cargadores en su configuración de paquete web:

module: { loaders: [ { test: //.jsx$/, exclude: /node_modules/, loader: "babel" }, { test: //.css$/, loader: "style!css" } ] }


Finalmente me he dado cuenta de que este error no se origina en la etapa de compilación, sino en el tiempo de ejecución. Como se trata de una aplicación ismórfica, los componentes y las dependencias que tengan se analizarán primero en el servidor (es decir, en el nodo). Esto es lo que está causando el error.

Gracias por todas las sugerencias, publicaré más si / cuando descubro cómo tener hojas de estilo por componente en una aplicación isomorfa.


No puede requerir css en el componente que está procesando en el servidor. Una forma de resolverlo es comprobar si se trata de un navegador antes de requerir css.

if (process.env.BROWSER) { require("./style.css"); }

Para que sea posible, debe establecer process.env.BROWSER en false (o eliminarlo) en el servidor server.js

delete process.env.BROWSER; ... // other server stuff

y configurarlo para el navegador. Lo haces con DefinePlugin de webpack en config - webpack.config.js

plugins: [ ... new webpack.DefinePlugin({ "process.env": { BROWSER: JSON.stringify(true) } }) ]

Puedes ver esto en acción en la aplicación Isomorphic500 de gpbl.


Probablemente tenga un error en la configuración de su Webpack donde está usando babel-loader para todos los archivos, y no solo para los archivos .js . Desea utilizar un cargador css para archivos .css .

Pero no debe usar la import para cargar ningún otro módulo aparte de los módulos de Javascript, porque una vez que se implementan las importaciones en los navegadores, solo podrá importar archivos de Javascript. Use require en cambio en los casos en que necesite funcionalidad específica de Webpack.

POSTE ORIGINAL

Los usos de Webpack require y Babel le permite usar la import desde ES6 que hace casi lo mismo (y Babel transpila la importación a una declaración obligatoria), pero no son intercambiables. La función de require paquetes web le permite especificar más que solo un nombre de módulo, también le permite especificar cargadores, lo que no puede hacer con las import ES6. Por lo tanto, si desea cargar un archivo CSS, debe usar require lugar de import .

La razón es que Babel es solo un transpiler para lo que viene en ES6, y ES6 no le permitirá importar archivos CSS. Entonces Babel tampoco te permitirá hacer eso.


Si está compilando una aplicación isomórfica con ES6 y desea incluir CSS al renderizar en el servidor (importante para que los estilos básicos puedan enviarse al cliente en la primera respuesta HTTP) @withStyles vistazo al decorador @withStyles ES7 utilizado en React Starter Kit .

Esta pequeña belleza ayuda a asegurar que los usuarios vean su contenido con estilos cuando la página se procesa por primera vez. Aquí hay un ejemplo de aplicación isomórfica que estoy construyendo aprovechando esta técnica. Solo busca en la base de código @withStyles para ver cómo se usa. Va algo así como esto:

import React, { Component, PropTypes } from ''react''; import styles from ''./ScheduleList.css''; import withStyles from ''../../decorators/withStyles''; @withStyles(styles) class ScheduleList extends Component {


También encontré el mismo problema cuando quiero hacer el renderizado del lado del servidor.

Así que escribo un complemento postcss-hash-classname , postcss-hash-classname .

No necesita css directamente.

Necesita su archivo css classname js.

Como todo lo que necesita es un archivo js, ​​puede hacer el procesamiento del lado del servidor como de costumbre.

Además, este complemento también usa su nombre de clase y ruta de archivo para generar hash único para resolver el problema de alcance css.

¡Puedes probarlo!



Tuvimos un problema similar con nuestra aplicación isomorfa (y muchos otros problemas, puedes encontrar detalles aquí ). En cuanto al problema con la importación de CSS, al principio, estábamos usando process.env.BROWSER. Más tarde cambiamos a babel-plugin-transform-require-ignore . Funciona perfectamente con babel6.

Todo lo que necesita es tener la siguiente sección en su .babelrc

"env": { "node": { "plugins": [ [ "babel-plugin-transform-require-ignore", { "extensions": [".less", ".css"] } ] ] } }

Después de eso, ejecuta tu aplicación con BABEL_ENV = ''node''. Como eso:

BABEL_ENV=''node'' node app.js.

Aquí hay un ejemplo de cómo puede verse una configuración de producción.


Utilicé este plugin de babel con éxito para resolver un problema similar con menos svg e imágenes. Pero debería funcionar con activos que no sean js.

Reescribe todas las importaciones de activos en variables, por lo que siempre que ejecute el código compilado solo en el servidor y tenga un paquete integrado con el paquete web para el cliente, debería estar bien.

El único inconveniente es que solo funciona con importaciones con nombre, por lo que deberá:

import styles from ''./styles.css'';

para hacer que funcione